#!/bin/sh
################################################################################
#
# CMe3100 restore software configuration script.
#
################################################################################

STATE_CFG="/application/CMe3100/internal/state.config"
SQL_LOG_DB="/application/CMe3100/appdata/currentstorage/log_db_cme3100.sqlite"

# ------------------------------------------------------------------------------
# Log to console and insert message in log database.
#
# $1 : message to log
# ------------------------------------------------------------------------------
log() {
  echo "$1"

  NOW=$(date +%s000)
  sqlite3 $SQL_LOG_DB "INSERT INTO Log (created, severity, message, source, deviceId) VALUES ('$NOW', -1, '$1', 'System: restore sw', -1);"
}
# ------------------------------------------------------------------------------

# ------------------------------------------------------------------------------
# Check if there is a progress file, create it if it does not already exist.
#
# $1 : name of progress file
# ------------------------------------------------------------------------------
checkProgressFile() {
  if [ -f "$1" ]; then
    log "Progress file $1 found."
  else
    log "Progress file $1 not found. Creating it."
    touch $1
    echo 0 >$1
  fi
}
# ------------------------------------------------------------------------------

# ------------------------------------------------------------------------------
# Clean up after restore operation
#
# $1 : restore archive to remove
# $2 : progress file to remove
# ------------------------------------------------------------------------------
cleanUp() {
  rm -rf $1
  rm -f $2
}
# ------------------------------------------------------------------------------

# ------------------------------------------------------------------------------
# Restore finished
# ------------------------------------------------------------------------------
completed() {
  if ! grep -q event.backup.restored ${STATE_CFG}; then
    # ugly syntax for EOF to work
    log "Updating state.cfg"
    cat <<EOF >>${STATE_CFG}
event.backup.restored=true
EOF
  fi

  sed -i "s/^event.backup.restored=.*/event.backup.restored=true/g" $STATE_CFG

  log "Rebooting"

  reboot -f
}
# ------------------------------------------------------------------------------

# ------------------------------------------------------------------------------
# Extract BZ2 compressed archive
#
# $1 : the directory in which the archive is located
# $2 : the file to write state information to
# $3 : next state if this step is successfully completed
# ------------------------------------------------------------------------------
extractBz2Archive() {
  archiveDirectory=$1
  progressFile=$2
  nextState=$3

  if ls $archiveDirectory*.tar &>/dev/null; then
    log "Removing lingering tar files in restore archive directory $archiveDirectory"
    rm -f /application/restoresw/*.tar
  fi

  log "Looking for restore archive in folder $archiveDirectory"
  if ls $archiveDirectory*.tar.bz2 &>/dev/null; then
    log "Extracting bz2 restore archive(s)"
    bzip2 -d $archiveDirectory*.tar.bz2
    if [ $? ]; then
      echo $nextState >$progressFile
    fi
  else
    log "Restoration failed, no tar.bz2 archives found"
    echo 400 >$progressFile
  fi
}
# ------------------------------------------------------------------------------

# ------------------------------------------------------------------------------
# Extract TAR compressed archive
#
# $1 : the directory in which the archive is located
# $2 : the file to write state information to
# $3 : next state if this step is successfully completed
# ------------------------------------------------------------------------------
extractTarArchive() {
  archiveDirectory=$1
  progressFile=$2
  nextState=$3

  log "Extracting tar restore archive(s)"
  tar xvf $archiveDirectory*.tar -C $archiveDirectory
  if [ $? ]; then
    echo $nextState >$progressFile
  fi
}
# ------------------------------------------------------------------------------

# ------------------------------------------------------------------------------
# Remove the compress files
#
# $1 : the directory in which the archive is located
# $2 : the file to write state information to
# $3 : next state if this step is successfully completed
# ------------------------------------------------------------------------------
deleteCompressedFiles() {
  archiveDirectory=$1
  progressFile=$2
  nextState=$3

  log "Removing compressed files from $archiveDirectory"
  rm -f $archiveDirectory*.tar && rm -f $archiveDirectory*.tar.bz2
  if [ $? ]; then
    echo $nextState >$progressFile
  fi
}
# ------------------------------------------------------------------------------

# ------------------------------------------------------------------------------
# Restore interface definitions
#
# $1 : the directory in which the archive is located
# $2 : the file to write state information to
# $3 : next state if this step is successfully completed
# ------------------------------------------------------------------------------
restoreInterfaces() {
  archiveDirectory=$1
  progressFile=$2
  nextState=$3

  interfacesFile=$archiveDirectory'interfaces'

  if [ -f $interfacesFile ]; then
    log "Restoring network interfaces file"
    mv $interfacesFile /etc/network/interfaces
    if [ $? ]; then
      echo $nextState >$progressFile
    fi
  else
    echo $nextState >$progressFile
  fi
}
# ------------------------------------------------------------------------------

# ------------------------------------------------------------------------------
# Restore current storage if available in the archive.
#
# $1 : the directory in which the archive is located
# $2 : the file to write state information to
# $3 : next state if this step is successfully completed
# $4 : fail state to jump to if restore fails (OPTIONAL)
# ------------------------------------------------------------------------------
restoreCurrentStorage() {
  archiveDirectory=$1
  progressFile=$2
  nextState=$3
  failState=$4

  currentStorageDirectory=$archiveDirectory'currentstorage'
  if [ -d $currentStorageDirectory ]; then
    log "Restoring current storage"
    rm -rf /application/CMe3100/appdata/currentstorage
    mv $currentStorageDirectory /application/CMe3100/appdata/currentstorage

    if [ $? ]; then
      # Since we just got a new database, let's "duplicate" this log message
      log "Storage restored"
      echo $nextState >$progressFile
    elif [ ! -z "$failState" ]; then
      log "Failed to restoreStorage. $?"
      echo $failState >$progressFile
    fi
  elif [ ! -z "$failState" ]; then
    log "Failed to restoreStorage. Restore archive does not contain currentstorage folder."
    echo $failState >$progressFile
  else
    echo $nextState >$progressFile
  fi
}
# ------------------------------------------------------------------------------

# ------------------------------------------------------------------------------
# Restore current configuration.
#
# $1 : the directory in which the archive is located
# $2 : the file to write state information to
# $3 : next state if this step is successfully completed
# ------------------------------------------------------------------------------
restoreCurrentConfig() {
  archiveDirectory=$1
  progressFile=$2
  nextState=$3

  DEFAULT_TDF="/application/CMe3100/appdata/defaultconfig/common/common.tdf"
  currentConfigDirectory=$archiveDirectory'currentconfig'

  if [ -d $currentConfigDirectory ]; then
    log "Restoring current configuration"
    rm -rf /application/CMe3100/appdata/currentconfig

    mv $currentConfigDirectory /application/CMe3100/appdata/currentconfig
    log "Restoring current configuration complete"
	
	cp $DEFAULT_TDF /application/CMe3100/appdata/currentconfig/common
    log "Restoring common.tdf to current version"

    if [ $? ]; then
      echo $nextState >$progressFile
    fi
  else
    log "Keeping current config"
    echo $nextState >$progressFile
  fi
}
# ------------------------------------------------------------------------------

# ------------------------------------------------------------------------------
# Restore plugin configuration.
#
# $1 : the directory in which the archive is located
# $2 : the file to write state information to
# $3 : next state if this step is successfully completed
# ------------------------------------------------------------------------------
restoreCurrentPluginConfig() {
  archiveDirectory=$1
  progressFile=$2
  nextState=$3

  currentPluginConfigDirectory=$archiveDirectory'currentpluginconfig'
  if [ -d $currentPluginConfigDirectory ]; then
    log "Restoring plugin configuration"
    rm -rf /application/CMe3100/appdata/currentpluginconfig
    mv $currentPluginConfigDirectory /application/CMe3100/appdata/currentpluginconfig
    if [ $? ]; then
      echo $nextState >$progressFile
    fi
  else
    log "Keeping plugin configuration"
    echo $nextState >$progressFile
  fi
}
# ------------------------------------------------------------------------------

# ------------------------------------------------------------------------------
# Restore software
# ------------------------------------------------------------------------------
restoreSoftware() {
  log "Start restoring software version"

  archiveDirectory="/application/restoresw/"
  progressFile="/application/restore_progress.tmp"
  checkProgressFile $progressFile

  while true; do
    state=$(cat $progressFile)
    case "$state" in
    0)
      extractBz2Archive $archiveDirectory $progressFile 1
      ;;
    1)
      extractTarArchive $archiveDirectory $progressFile 2
      ;;
    2)
      deleteCompressedFiles $archiveDirectory $progressFile 3
      ;;
    3)
      restoreInterfaces $archiveDirectory $progressFile 4
      ;;
    4)
      restoreCurrentStorage $archiveDirectory $progressFile 5
      ;;
    5)
      restoreCurrentConfig $archiveDirectory $progressFile 6
      ;;
    6)
      restoreCurrentPluginConfig $archiveDirectory $progressFile 7
      ;;
    7)
      if [ -d /application/restoresw/currentlinuxconfig ]; then
        log "Restoring linux config"
        rm -rf /application/CMe3100/appdata/currentlinuxconfig
        mv /application/restoresw/currentlinuxconfig /application/CMe3100/appdata/currentlinuxconfig
        if [ $? ]; then
          echo 200 >$progressFile
        fi
      else
        log "Keeping linux config"
        echo 200 >$progressFile
      fi
      ;;
    200)
      log "Restored sofware successfully"
      cleanUp "/application/restoresw/" $progressFile
      completed
      ;;
    400)
      log "Restore of software unsuccessful. See log for more information"
      cleanUp "/application/restoresw/" $progressFile
      completed
      ;;
    esac
  done
}
# ------------------------------------------------------------------------------

# ------------------------------------------------------------------------------
# Restore configuration
# ------------------------------------------------------------------------------
restoreConfig() {
  log "Start restoring current configuration"

  archiveDirectory="/application/restoreconfig/"
  progressFile="/application/restore_config_progress.tmp"
  checkProgressFile $progressFile

  while true; do
    state=$(cat $progressFile)
    case "$state" in
    0)
      extractBz2Archive $archiveDirectory $progressFile 1
      ;;
    1)
      extractTarArchive $archiveDirectory $progressFile 2
      ;;
    2)
      deleteCompressedFiles $archiveDirectory $progressFile 3
      ;;
    3)
      log "Restoring current configuration (keeping secured configuration)"
      # keep secured folder since it doesn't exists in a configuration backup
      if [ -d /application/CMe3100/appdata/currentconfig/secured ]; then
        mv /application/CMe3100/appdata/currentconfig/secured /application/restoreconfig/currentconfig
      fi
      rm -rf /application/CMe3100/appdata/currentconfig
      mv /application/restoreconfig/currentconfig /application/CMe3100/appdata/currentconfig
      if [ $? ]; then
        echo 4 >$progressFile
      fi
      ;;
    4)
      restoreCurrentPluginConfig $archiveDirectory $progressFile 200
      ;;
    200)
      log "Restored config successfully"
      cleanUp "/application/restoreconfig/" $progressFile
      completed
      ;;
    400)
      log "Restore of config unsuccessful. See log for more information"
      cleanUp "/application/restoreconfig/" $progressFile
      completed
      ;;
    esac
  done
}
# ------------------------------------------------------------------------------

# ------------------------------------------------------------------------------
# Restore storage
# ------------------------------------------------------------------------------
restoreStorage() {
  log "Start restoring current storage"

  archiveDirectory="/application/restorestorage/"
  progressFile="/application/restore_storage_progress.tmp"
  checkProgressFile $progressFile

  while true; do
    state=$(cat $progressFile)
    case "$state" in
    0)
      extractBz2Archive $archiveDirectory $progressFile 1
      ;;
    1)
      extractTarArchive $archiveDirectory $progressFile 2
      ;;
    2)
      deleteCompressedFiles $archiveDirectory $progressFile 3
      ;;
    3)
      restoreCurrentStorage $archiveDirectory $progressFile 200 400
      ;;
    200)
      log "Restored storage successfully"
      cleanUp "/application/restorestorage/" $progressFile
      completed
      ;;
    400)
      log "Restore of storage unsuccessful. See log for more information"
      cleanUp "/application/restorestorage/" $progressFile
      completed
      ;;
    esac
  done
}
# ------------------------------------------------------------------------------

case "$1" in
start)
  if [ -d /application/restorestorage ]; then
    restoreStorage
  elif [ -d /application/restoresw ]; then
    restoreSoftware
  elif [ -d /application/restoreconfig ]; then
    restoreConfig
  else
    log "Nothing to restore, normal boot"
  fi
  ;;
stop)
  echo "Not applicable"
  ;;
*)
  echo "Usage: $0 {start}"
  exit 1
  ;;
esac

exit 0
