#!/usr/bin/env bash
################ Restore/Extract .wzt backup/bundle ################
# .wzt file is a tar.zst (created using ${TAR_CMD} --zstd -cvf wztfile.wzt directory)
# see script-backup
# For restoring we need "Prefix" name and Resore "Size" from wzt file
# Steps:
# 0.  Check if winezprefix is writable before restoring
# 1.  Extract prefix name and wzt-info.yml to tmp dir and put that in wzt_var
# 2.  Show Content of extracted wzt-info.yml file before restoring
# 3.  Determine required disk space to extract the wzt file
# 4.  Restoring wzt file
# 5.  Preprocess backup values and variables in the extracted prefix
# 6.  Create desktop dir, process Info file
# 7.  Cleanup broken links in winezgui shortcuts directory
# 8.  Update desktop menus and Icon cache
# 9.  Get Game name from desktop file
# 10. Ask if the user wants to start the restored game
winezgui-restore-wzt()
{
  HEADER="$(basename ${0}): ${FUNCNAME[0]}"
    
  SOURCE "script-check-variables-loaded-or-not"
  script-check-variables-loaded-or-not
  dbug "I: $(basename ${0}): Launched ${FUNCNAME[0]}"

  cd "${PREFIXES_DIR}"

  # 0. Check whether WINEZGUIDIR is writable before restoring
  if ! [ -w "${PREFIXES_DIR}" ]; then
       dbug "I: ${HEADER}: ${PREFIXES_DIR} is not writable. Aborting!"
       ${ZENITY_CMD} --error --title "${APP_WITH_VER}" \
              --text "${PREFIXES_DIR} is not writable"
       WineZGUI_Window
  fi
 
  # wzt-info.yml has info about uncompressed size and game name
  WZT_INFO_FILE="wzt-info.yml"
 
  # Get basename of wztfile without path
  WZT_NAME=$(basename "${WZT_FILE}")
 
  # 1. Extract prefixname and wzt-info.yml file to tmp dir from wzt file
 
  # 1.1 Create a temporary directory to extract wzt-info.yml file
  export WINEZGUI_TEMPDIR="${WINEZGUIDIR}/tmp"
  mkdir -p  ${WINEZGUI_TEMPDIR}
 
  # 1.2  Extract Prefix Name: Get the directory name from wzt file
  (WZT_PREFIX=$(${TAR_CMD} -tf "${WZT_FILE}"|head -n2|grep "/"|cut -f1 -d "/"); \
   echo "$WZT_PREFIX" > "${WINEZGUI_TEMPDIR}/PREFIX_NAME_TEMP"; \
 
  # 1.3 Extract wzt-info.yml file to WINEZGUI_TEMPDIR; Show progress using zenity
  ${TAR_CMD} --occurrence=1 --extract -O -f "${WZT_FILE}" ${WZT_INFO_FILE} \
  | tee ${WINEZGUI_TEMPDIR}/${WZT_INFO_FILE} &) | \
  (${ZENITY_CMD}   --progress  --pulsate  --no-cancel  --auto-close  \
         --title="${APP_WITH_VER} - Restore... Please wait." \
         --width=500 --text="Getting info from\n${WZT_NAME}")
 
  # Zenity on Cancel sends 1 and 0 on OK
  ZENITY_STATUS=$?

  WZT_PREFIX=$(cat "${WINEZGUI_TEMPDIR}/PREFIX_NAME_TEMP")
  rm "${WINEZGUI_TEMPDIR}/PREFIX_NAME_TEMP"

  dbug "I: ${HEADER}: Prefix from ${WZT_FILE} is ${WZT_PREFIX}";
 
  # 1.4 If the user cancels extracting wzt-info.yml using tar xfO
  # kill tar running in background
  # If zenity returns 1 (means either cancel or other error with tar xfO)
  if [ "${ZENITY_STATUS}" = "1" ]; then
       # Find the PID and kill the running tar command which has wzt in it
       unset PID_OF_TAR

       PID_OF_TAR=$(ps -aux|grep tar|grep -i "${WZT_NAME}"|sed "/.*grep -i.*/d" \
                   |sed "s/  */ /g" |cut -f2 -d " ")
       if ! [ -z "$PID_OF_TAR" ]; then # if pid is found kill it
            kill -9 ${PID_OF_TAR} \
            && dbug "I: ${HEADER}: Getting Info Cancelled!"
            WineZGUI_Window
       fi
  else
       dbug "I: ${HEADER}: Read ${WZT_NAME} Successfully!"
  fi
 
  # 1.5 Read the wztfile contents into a variable
  WZT_VAR=$(cat "${WINEZGUI_TEMPDIR}/${WZT_INFO_FILE}"|tr "\n" "|")
 
  # 1.6 If the WZT_VAR is empty, then WZT_VAR could not read from wzt-info.yml
  # Force extract..
  if [ -z "${WZT_VAR}" ]; then
       dbug "I: ${HEADER}: ${WZT_INFO_FILE} not found in tar archive"
       ${ZENITY_CMD} --question  --title "${WZT_NAME} Force extract?" \
              --no-wrap --text "${WZT_INFO_FILE} not found, extract anyhow?"
       ANSWER=$?
       if [ ${ANSWER} -eq 0 ]; then
            (nice -n 19 ${TAR_CMD} --zstd -xvf "${WZT_FILE}" -C "${PREFIXES_DIR}" --transform \
             "s|XOUSERXO|${USER}|g" &)| 
            (${ZENITY_CMD} --progress --width=500            \
             --title="Restoring ${WZT_FILE}!"         \
             --text="Force Extracting ${WZT_FILE}..." \
             --pulsate --auto-close)
      fi
      SOURCE "winezgui-identity-restore-all"
      winezgui-identity-restore-all

      # Show menu after extraction
      SOURCE "winezgui-launch"
      winezgui-launch
      WineZGUI_Window

  fi
 
  # 2. Show Content of extracted wzt-info.yml file before restoring
  # 2.1 Get Game/App name from the wzt-info.yml file
  GAME_NAME=$(echo ${WZT_VAR}|sed "s/|/\n/g"|grep -E "Name*:"|cut -f2 -d ":")
  dbug "I: ${HEADER}: Name: ${GAME_NAME}"
 
  # 2.1 format the wzt-info.yml content for display using zenity
  TEXT1="$(while read -r line; do echo $line|sed '0,/:/{s/:/ \`: /}'|sed -e 's/$/XX/g'|sed 's/^/<tt><b>/g'|sed 's/`:/<\/b>`:/g'; done < ${WINEZGUI_TEMPDIR}/${WZT_INFO_FILE})"
  TEXT_MSG="$(echo $TEXT1|sed -e 's/XX /<\/tt>\n/g'|sed -e 's/XX/<\/tt>\n/g'|column -t -s '\`')"

  ${ZENITY_CMD} --question --no-wrap \
         --title "Restore ${GAME_NAME}?" --text "${TEXT_MSG}"
  ANSWER=$?
 
  # 2.3 if User selects cancel / no
  if [ "$ANSWER" = "1" ]; then
       dbug "I: ${HEADER}: Restoring WineZGUI file. Cancelled!"
       WineZGUI_Window
  fi
 
  # 2.4 Remove ${WINEZGUI_TEMPDIR} after getting data into WZT_VAR variable
  rm -rf ${WINEZGUI_TEMPDIR}
 
  # 3. Determine required disk space to extract the wzt file
  dbug "I: ${HEADER}: Determining available space for extraction"
 
  # 3.1 Determine available disk space (df -h) of $HOME / winezgui prefix
  WINEZGUIDIR_DF=$(df -h "${WINEZGUIDIR}"|tr -s " "|tail -n1|cut -f4 -d " ")
  #Check whether df gave a value or not
  if [ -z "${WINEZGUIDIR_DF}" ]; then
       echo "-------------------- Error --------------------------"
       echo "Error: ${FUNCNAME[0]}: WINEZGUIDIR_DF not assigned"
       echo "-------------------- Error --------------------------"
  fi
  dbug "I: ${HEADER}: Available space is: ${WINEZGUIDIR_DF}"
 
  # 3.2 Convert the above $WINEZGUIDIR_DF into bytes for comparison
  WINEZGUIDIR_DF_IN_BYTES=$(echo ${WINEZGUIDIR_DF}|numfmt --from iec)
 
  # 3.3 Fetch required disk space from wzt variable
  dbug "I: ${HEADER}: Fetching required disk space from ${WZT_INFO_FILE}"
  WZT_F_UNCOMPRESSED_SIZE=$(echo ${WZT_VAR}|sed "s/|/\n/g"|grep "Size" \
                           |cut -f2 -d ":"|numfmt --from iec)
  dbug "I: ${HEADER}: Required space: ${WZT_F_UNCOMPRESSED_SIZE}"
 
  # 3.4 If Target directory does not have sufficient space, abort backup
  dbug "I: ${HEADER}: Checking Available size is more than Required space"
  if [ ${WINEZGUIDIR_DF_IN_BYTES} -gt ${WZT_F_UNCOMPRESSED_SIZE} ];then
       dbug "I: ${HEADER}: ${WINEZGUIDIR} has enough available disk space!"
  else
       echo "W: ${HEADER}: ${WINEZGUIDIR} does not have free disk space!!!"
       unset MSG
       MSG+="${WINEZGUIDIR} has only ${WINEZGUIDIR_DF}"
       MSG+=" "
       MSG+="free disk space left!\n"0
       MSG+="Prefix backup requires ${WZT_F_UNCOMPRESSED_SIZE} free disk space."
 
       # 3.4.1 Inform user on insufficient disk space
       ${ZENITY_CMD} --warning --no-wrap --title "Insufficient Disk Space!" \
              --text "${MSG}"
       echo "E: Restore: Insufficient Disk Space, Cancelled!"
       WineZGUI_Window
 
  fi
 
  # 4. Restoring wzt file
  dbug "I: ${HEADER}: Restoring ${WZT_NAME}"
 
  # 4.1 Check: Existing prefix with the same name!?
  if [ -d "${PREFIXES_DIR}/${WZT_PREFIX}" ]; then
       # If yes, ask whether to overwrite existing prefix
       ${ZENITY_CMD} --question --title "Restore ${GAME_NAME}" \
              --text "${WZT_PREFIX} already exists, overwrite?"
       ANSWER=$?
       if [ "${ANSWER}" = "1" ]; then
            dbug "I: ${HEADER}: User Cancelled Overwriting! Aborting!"
            WineZGUI_Window
       else
            dbug "I: ${HEADER}: Overwriting existing ${WZT_NAME}"
       fi
  fi
 
  # 4.2 Extract file to WineZGUI Prefix and show gui progress dialog
  # Change directory name XOUSERXO to username on restore
  dbug "I: ${HEADER}: Extracting ${WZT_NAME} at ${PREFIXES_DIR}"
  (${TAR_CMD} --zstd -xvf "${WZT_FILE}" -C "${PREFIXES_DIR}" --transform \
           "s|XOUSERXO|${USER}|g" &)| \
  (${ZENITY_CMD} --progress --width=500                    \
          --title="Restoring ${GAME_NAME}!"         \
          --text="Extracting ${WZT_FILE}..."        \
          --pulsate --auto-close)
 
 
  ZENITY_STATUS=$?
 
  # 4.2.1 If user cancels extraction,  zenity will return 1
  if [ "${ZENITY_STATUS}" = "1" ]; then
       # If the user cancels extraction of wzt game bundle during extraction
       # kill the running tar command which has wzt in it
       unset PID_OF_TAR
       PID_OF_TAR=$(ps -aux|grep tar|grep -i wzt|sed "/.*grep -i.*/d" \
                           |sed "s/  */ /g" |cut -f2 -d " ")
 
       if ! [ -z "$PID_OF_TAR" ]; then
            kill -9 ${PID_OF_TAR} \
            && dbug "I: ${HEADER}: Cancelled! Stopped extraction!"
            # Ask the user whether to delete partially extracted or let it be
            ${ZENITY_CMD} --question --title "Extraction Cancelled!" \
                   --text "Delete ${WZT_PREFIX} prefix?"
            ANSWER=$?
            if [ "${ANSWER}" = "0" ]; then
                 # User selected Delete
                 rm -rf "${PREFIXES_DIR}/${WZT_PREFIX}" && \
                 dbug "I: ${HEADER}: Removed ${PREFIXES_DIR}/${WZT_PREFIX}"
                 # Cleanup broken links in winezgui shortcuts directory
                 find ${APPLICATIONSDIR} -maxdepth 1 -iname "${SHORTCUT_PREFIX}*" -xtype l -delete 2>/dev/null && \
                 dbug "I: ${HEADER}: Removed broken WineZGUI .desktop links"
            else
                 # user wants to keep prefix
                 dbug "I: ${HEADER}: Keeping extracted ${WINEZGUIDIR}/${WZT_PREFIX}"
                 # Restore Sucess Message
            fi
            MSG=("${WZT_PREFIX} Restore Cancelled!")
            WineZGUI_Window
 
       else
            # If no pid of tar is found means extraction already completed
            dbug "I: ${HEADER}: Extracted ${WZT_FILE} Successfully!"
       fi # if ! [ -z "$PID_OF_TAR" ]; then
  fi # [ "${ZENITY_STATUS}" = "1" ]; then
 
  # Game prefixes will have game.desktop game.sh and game.png files in it.
  FOUND_PREFIX_DIR="${PREFIXES_DIR}/${WZT_PREFIX}"
  FOUND_DESKTOP_FILE="${FOUND_PREFIX_DIR}/${WZT_PREFIX}.desktop"
  FOUND_SCRIPT_FILE="${FOUND_PREFIX_DIR}/${WZT_PREFIX}.sh"
  FOUND_INFOFILE="${FOUND_PREFIX_DIR}/Info.yml"
 
  # 5. Preprocess backup values and variables in the extracted prefix
  # cd "${PREFIXES_DIR}/${WZT_PREFIX}"
  cd "${PREFIXES_DIR}"
  export PREFIXNAME="${WZT_PREFIX}"
  dbug "I: ${HEADER}: Processing files inside ${WZT_PREFIX} for use!"
  
  # Restore should get Wine version from wzt-info.yml (to keep backward compatibility)
  # Fixes runner and wineversion error on restore
  RESTORE_WINEVER=$(grep -i "Wine:" "${PREFIXES_DIR}/${WZT_PREFIX}/wzt-info.yml"|cut -f2 -d ":")
  if [ ! -z "${RESTORE_WINEVER}" ]; then
       sed "s|XOWINEVERXO|${RESTORE_WINEVER}|g" -i  $(find "${PREFIXES_DIR}/${WZT_PREFIX}" -maxdepth 1 -type f)
  fi
  
  SOURCE "winezgui-identity-restore"
  winezgui-identity-restore "${PREFIXES_DIR}/${WZT_PREFIX}"
 
  # 6 Create desktop dir, process Info file
  # 6.1 Create required applications directory for .desktop files
  unset MAKEDIR
  if [ "${INSTALL_TYPE}" = "flatpak" ]; then
       # 6.1.1 Make Shortcuts dir for flatpak
       MAKEDIR=("${HOME}/.local/share/applications/")
       MAKEDIR+="winezgui/${FLATPAK_ID}"
       mkdir -p "${MAKEDIR}"
       dbug "I: ${HEADER}: Created Shortcuts dir: ${MAKEDIR}"
 
       # 6.1.2 Add flatpak name to XOFLATPAKIDXO
       sed "s|XOFLATPAKIDXO|${FLATPAK_NAME}|g" -i "${FOUND_INFOFILE}"
       # if Install:system  => Install:flatpak
       sed "s|Install:system|Install:flatpak|g" -i  "${FOUND_INFOFILE}"
       # 6.1.3 If flatpak: FLATPAKID not found add it
       if [ ! $(grep "Flatpak:" "${FOUND_INFOFILE}") ]; then
            echo "Flatpak:${FLATPAK_NAME}" >> "${FOUND_INFOFILE}"
       fi
  else
       # 6.1.1 Make Shortcuts dir for flatpak
       MAKEDIR=("${HOME}/.local/share/applications/")
       MAKEDIR+="winezgui"
       mkdir -p "${MAKEDIR}"
       dbug "I: ${HEADER}: Created Shortcuts dir: ${MAKEDIR}"
       # 6.1.2 Remove flatpak line containing XOFLATPAKIDXO for system install
       sed "/.*XOFLATPAKIDXO.*/d" -i "${FOUND_INFOFILE}"
       # if Install:flatpak  => Install:system
       sed "s|Install:flatpak|Install:system|g" -i  "${FOUND_INFOFILE}"
  fi
 
  # If NO_SHORTCUTS= NOTHING/EMPTY then create shortcuts
  echo "xoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxo" 
  if [ -z "${NO_SHORTCUTS}" ]; then
       # 6.1.2 # Find all desktop files and create shortcuts in the menu
       for i in $(find ${FOUND_PREFIX_DIR} -maxdepth 1 -type f -iname "*.desktop"); do 
          BASENAME=$(basename "${i}")
          chmod +rx "${i}"
          ln -svf $(realpath $i) "${APPLICATIONSDIR}/${SHORTCUT_PREFIX}_${BASENAME}";
       done
       dbug "I: Script: Shortcut is created at ${APPLICATIONSDIR}/${SHORTCUT_PREFIX}_${BASENAME}"
  else 
       dbug "I: Script: WARNING: Shortcut NOT CREATED at ${APPLICATIONSDIR}/${SHORTCUT_PREFIX}_${BASENAME}"
  fi

  # Create a restored.text to update wineprefix
  # without mono and gecko install dialog which
  # winezgui-create-prefix checks on different versions of wine
  # on 1st lauch on restoring
  # we'll use restored.txt to launch wineboot with DLLoverrides
  
  echo "yes" > ${FOUND_PREFIX_DIR}/restored.txt

  # 7. Cleanup broken links in winezgui shortcuts directory
  find ${APPLICATIONSDIR} -maxdepth 1 -iname "${SHORTCUT_PREFIX}*" -xtype l -delete 2>/dev/null && \
  dbug "I: ${HEADER}: Removed broken WineZGUI .desktop links"

  # 8. Update desktop menus and Icon cache
  # Clean up broken shortcuts and update shortcuts menu
  SOURCE "winezgui-remove-broken-links"
  winezgui-remove-broken-links

 
  # Find other files which has username in it.
  # Read from file
  if [ -f "${FOUND_PREFIX_DIR}/FILES_WITH_USERNAME.txt" ]; then
       SOURCE "winezgui-identity-restore-from-drive-c-files"
       winezgui-identity-restore-from-drive-c-files "${FOUND_PREFIX_DIR}"
  fi
  
  LAUNCH_FILE_NAME=$(basename ${FOUND_SCRIPT_FILE})


#   if [ -f "${FOUND_SCRIPT_FILE}" ]; then
#        # 10. Ask if the user wants to start the restored game
#        if ${ZENITY_CMD} --question --no-wrap --width=200    \
#                  --title="WineZGUI Backup Restored!" \
#                  --text="Launch: ${LAUNCH_FILE_NAME}?"
#        then
#             # Start the Game script and exit main app
#             dbug "I: ${HEADER}: Launching Script for" \
#                  "the restored game..."
#             bash ${FOUND_SCRIPT_FILE}
#             exit 0
#        fi # ${ZENITY_CMD} --question
#   else
#        SOURCE "script-list-available-launch-shortcuts"
#        script-list-available-launch-shortcuts ${FOUND_PREFIX_DIR}
#        "${SELECTED_SCRIPT}" &
#        exit 0
#   fi

  # set x permissions
  chmod +rx "${DESKTOPFILE}" "${SCRIPTFILE}" "${S_SCRIPTFILE}" "${S_DESKTOPFILE}" "${NEW_SCRIPT_FILE}" "${NEWDESKTOPFILE}" "${NEWSCRIPTFILE}"

  # Just list the script files to launch
  SOURCE script-list-available-launch-shortcuts
  script-list-available-launch-shortcuts ${FOUND_PREFIX_DIR}
  "${SELECTED_SCRIPT}" &

#   # Make launch default for restored app/game
#   if [ -w "${FOUND_PREFIX_DIR}" ]; then
#             echo "Yes" > "${FOUND_PREFIX_DIR}/launch"
#             dbug "I: ${FOUND_PREFIX_DIR}: launch file created!"
#   fi
}
 
