#!/bin/sh

usage() {
   echo "Usage: restore [--textconfig] [--uiconfig] filename"
   echo ""
   echo "  e.g. # Replaces everything with config from a file called myBackup.zip"
   echo "       ./restore myBackup.zip"
   echo
   echo "       # Restores/adds only text configuration from a backup file"
   echo "       ./restore --textconfig myBackup.zip"
   echo
   echo "       # Restores/adds text and UI configuration from a backup file"
   echo "       ./restore --uiconfig --textconfig myBackup.zip"
   echo
   echo "Use this script to restore an openHAB configuration that was previously"
   echo "made with the openHAB 'backup' script, or selected config parts only."
   echo "Running without options will eradicate your current active config."
   echo "Use of either --...config option will keep all of your configuration,"
   echo "then add/overwrite text and/or UI configuration as per your specified" 
   echo "option with any of the files contained in the backup file."
   echo "Text configuration is all *.things, *.items, *.rules, *.scripts files"
   echo "in the openHAB config directories ${OPENHAB_CONF}/*."
   echo "User Interface config is all files in ${OPENHAB_USERDATA}/jsondb".
   echo
   echo "Backup directory: '$OPENHAB_BACKUPS'"
   echo "Set \$OPENHAB_BACKUPS to change the default backup directory."
}

setup(){
  bText="0"
  bUI="0"
  while [ "$1" != "" ]; do
    case $1 in
      -h | --help)
        usage
        exit 0
        ;;
      --textconfig)
        bText="1"
        ;;
      --uiconfig)
        bUI="1"
        ;;
      *)
        InputFile="$1"
        ;;
    esac
    shift
  done

  ## Ask to run as root to prevent us from running sudo in this script.
  if [ "$(id -u)" -ne 0 ]; then
    echo "Please run this script as root! (e.g. use sudo)" >&2
    exit 1
  fi

  command -v unzip >/dev/null 2>&1 || {
    echo "'unzip' program was not found, please install it first." >&2
    exit 1
  }

  ## Check to see if processes are running before restoring
  if [ "$bText" = "0" ] && [ "$bUI" = "0" ] && [ ! -z "$(pgrep -f "openhab.*java")" ]; then
    echo "openHAB is running! Please stop the process before restoring." >&2
    exit 1
  fi

  WorkingDir="$(cd "$(dirname "$0")" && cd ../.. && pwd -P)"

  ## Set path variables
  if [ -r /etc/profile.d/openhab.sh ]; then
    . /etc/profile.d/openhab.sh
  elif [ -r /etc/default/openhab ]; then
    . /etc/default/openhab
  fi
  if [ -z "$OPENHAB_CONF" ];       then OPENHAB_CONF="$WorkingDir/conf"; fi
  if [ -z "$OPENHAB_USERDATA" ];   then OPENHAB_USERDATA="$WorkingDir/userdata"; fi

  echo "Using '$OPENHAB_CONF' as conf folder..."
  echo "Using '$OPENHAB_USERDATA' as userdata folder..."

  ## Check two of the standard openHAB folders to make sure we're updating the right thing.
  if [ ! -d "$OPENHAB_USERDATA" ] || [ ! -d "$OPENHAB_CONF" ]; then
    echo "Configuration paths are invalid..." >&2
    echo "Try setting OPENHAB_USERDATA and OPENHAB_CONF environment variables." >&2
    exit 1
  fi

  # shellcheck disable=SC2012
  currentUser=$(ls -ld "$OPENHAB_USERDATA" | awk '{print $3}')
  # shellcheck disable=SC2012
  currentGroup=$(ls -ld "$OPENHAB_USERDATA" | awk '{print $4}')

  CurrentVersion="$(awk '/openhab-distro/{print $3}' "$OPENHAB_USERDATA/etc/version.properties")"

  ## Store anything in temporary folders
  TempDir="/tmp/openhab/restore"
  ## Clear older stuff if it exists
  rm -rf "${TempDir:?}"
  echo "Making Temporary Directory"
  mkdir -p "$TempDir" || {
    echo "Failed to make temporary directory: $TempDir" >&2
    exit 1
  }
}

echo "                                          "
echo "##########################################"
echo "          openHAB restore script          "
echo "##########################################"
echo "                                          "

setup "$@"

## Extract zip file
echo "Extracting zip file to temporary folder."

unzip -oq "$InputFile" -d "$TempDir" || {
  echo "Unable to unzip $InputFile, Aborting..." >&2
  exit 1
}

## Check for backup properties list.
if [ ! -f "$TempDir/backup.properties" ]; then
  echo "Backup was not created by openHAB scripts, please resort to a manual restore..." >&2
  exit 1
fi

## Grab information with backup.properties
str="$(awk '/version=/{print $1}' "$TempDir/backup.properties")"
BackupVersion=${str#*=}
str="$(awk '/timestamp=/{print $1}' "$TempDir/backup.properties")"
BackupTime=${str#*=}
str="$(awk '/user=/{print $1}' "$TempDir/backup.properties")"
OHUser=${str#*=}
str="$(awk '/group=/{print $1}' "$TempDir/backup.properties")"
OHGroup=${str#*=}

## Feedback to user
echo ""
echo " Backup Information:"
echo " -------------------"
echo " Backup Version         | $BackupVersion (You are on $CurrentVersion)"
echo " Backup Timestamp       | $BackupTime"
echo " Config belongs to user | $OHUser"
echo "             from group | $OHGroup"
echo ""
echo "Your current configuration will become owned by $currentUser:$currentGroup."
echo ""
if [ "$bText" = "1" ]; then
  echo "Text configuration will be restored."
fi
if [ "$bUI" = "1" ]; then
  echo "User Interface (UI) configuration will be restored to ${OPENHAB_USERDATA}/jsondb."
fi
echo "Any existing files with the same name will be replaced."
if [ "$bText" = "1" ] || [ "$bUI" = "1" ]; then
  echo "Any other files will be kept unchanged."
else
  echo "Any file without a replacement will be deleted."
fi
echo ""
printf "Okay to Continue? [y/N]: "
read -r answer
case "$answer" in
  [Yy]*)
    ;;
  *)
    echo "Cancelling restore..."
    rm -rf /tmp/openhab
    exit 0
    ;;
esac

if [ "$bText" = "0" ] && [ "$bUI" = "0" ]; then
  ## Move old configuration
  rm -rf /tmp/openhab/old
  mkdir -p /tmp/openhab/old
  echo "Moving system files in userdata to temporary folder"
  if [ -d "$OPENHAB_USERDATA/backups" ]; then
    mv "$OPENHAB_USERDATA/backups" /tmp/openhab/old || {
      echo "Could not move backup folder to temporary folder..." >&2
      exit 1
    }
  fi
  if [ -d "${OPENHAB_USERDATA:?}/etc" ]; then
    mv "${OPENHAB_USERDATA:?}/etc" /tmp/openhab/old || {
      echo "Could not move etc folder to temporary folder" >&2
      exit 1
    }
  fi

  echo "Deleting old userdata folder..."
  rm -rf "${OPENHAB_USERDATA:?}/"*

  echo "Restoring system files in userdata..."
  if [ -d /tmp/openhab/old/backups ]; then
    mv /tmp/openhab/old/backups "${OPENHAB_USERDATA:?}/" || {
      echo "Unable to move other backup files back..."
      exit 1
    }
  fi
  if [ -d /tmp/openhab/old/etc ]; then
    mv /tmp/openhab/old/etc "${OPENHAB_USERDATA:?}/" || {
      echo "Unable to move system files back..."
      exit 1
    }
  fi

  echo "Deleting old conf folder..."
  rm -rf "${OPENHAB_CONF:?}/"*
fi

## Restore configuration
echo "Restoring openHAB with backup configuration..."

## on full restore (no option) and --textconfig
if [ "$bUI" = "0" ]; then
  command cp -af "$TempDir/conf/"*     "${OPENHAB_CONF:?}/" || {
    echo "Failed to copy $TempDir/conf/ to $OPENHAB_CONF/..." >&2
    echo "Please check $TempDir and replace conf and userdata." >&2
    exit 1
  }
fi
## on full restore (no option)
if [ "$bText" = "0" ] && [ "$bUI" = "0" ]; then
  command cp -af "$TempDir/userdata/"* "${OPENHAB_USERDATA:?}/" || {
    echo "Failed to copy $TempDir/userdata/ to $OPENHAB_USERDATA/..." >&2
    echo "Please check $TempDir and replace userdata." >&2
    exit 1
  }
fi
## on --uiconfig
if [ "$bUI" = "1" ]; then
  command cp -af "$TempDir/userdata/jsondb/"* "${OPENHAB_USERDATA:?}/jsondb/" || {
    echo "Failed to copy $TempDir/userdata/jsondb/ to $OPENHAB_USERDATA/jsondb/..." >&2
    echo "Please check $TempDir and replace userdata." >&2
    exit 1
  }
fi

## Reset ownership
chown -R "$currentUser:$currentGroup" "$OPENHAB_USERDATA" || {
  echo "WARNING: Failed to change userdata folder permissions to $currentUser:$currentGroup" >&2
}
chown -R "$currentUser:$currentGroup" "$OPENHAB_CONF" || {
  echo "WARNING: Failed to change conf folder permissions to $currentUser:$currentGroup" >&2
}

echo "Deleting temporary files..."
rm -rf /tmp/openhab
echo "Backup successfully restored!"
echo ""
