#!/bin/bash

DIRECTORY="$(readlink -f "$(dirname "$0")")"

function error {
  echo -e "\e[91m$1\e[39m"
  exit 1
}

lastupdatecheck="$(cat "${DIRECTORY}/data/last-update-check")"
if [ -z $lastupdatecheck ];then
  echo "Warning: ${DIRECTORY}/data/last-update-check does not exist!"
  lastupdatecheck=0
fi

updateinterval="$(cat "${DIRECTORY}/data/settings/Check for updates")"

nocheck=0
#allowed values: Always, Daily, Weekly, Never
if [ "$updateinterval" == 'Never' ];then
  nocheck=1
  echo ''
elif [ "$updateinterval" == 'Daily' ];then
  #if updates checked today, don't check
  if [ "$(date +%j)" == "$lastupdatecheck" ];then
    nocheck=1
  fi
elif [ "$updateinterval" == 'Weekly' ];then
  #if updates checked less than 7 days ago, don't check
  if [ "$(date +%j)" -le "$((lastupdatecheck + 7))" ];then
    nocheck=1
  fi
elif [ "$updateinterval" == 'Always' ];then
  echo "Checking for updates now..."
elif [ -z "$updateinterval" ];then
  echo "Something isn"\'" right. Does ${DIRECTORY}/data/settings/Check for updates exist?"
else
  echo "Warning: Unrecognized update interval!"
fi

#fix for new years day
if [ "$lastupdatecheck" -gt "$(date +%j)" ];then
  nocheck=0
fi

#hidden flag: if $1 is 'onboot', then check for updates only for those apps that are installed.
onboot="$1"
if [ "$onboot" == 'onboot' ] || [ "$onboot" == 'installedonly' ];then
  onboot='onboot'
  
  #make sure user installed some apps first. If none installed, then Pi-Apps may be unwanted/unused.
  if [ "$(ls "${DIRECTORY}/data/status" | wc -l)" == 0 ];then
    echo "No apps have been installed yet, so exiting now."
    exit 0
  fi
  
  sleep 10 #wait 10 seconds, this is so the system will have booted all the way for an internet connection
fi

if [ $nocheck == 1 ];then
  echo "Won"\'"t check for updates today, because of the update interval is set to $updateinterval in Settings.
  To forcibly check for updates now, press any key within the next 20 seconds."
  read -n 1 -t 20 || exit 0
  echo ''
fi

#write today's date to file. Format is "number of days since jan 1"
echo "$(date +%j)" > "${DIRECTORY}/data/last-update-check"

#generate app update status info
updatable="$("${DIRECTORY}/manage" check-all)"
[ $? -ne 0 ] && error "check-all failed! Full output: $updatable"

#shorten to last line
updatable="$(echo "$updatable" | tail -1)"
if [ "$updatable" == '.' ];then
  updatable=''
fi

echo "updatable: $updatable"

#if check-all succeeded to download the repo to the update folder
if [ -d "${DIRECTORY}/update" ];then
  PREIFS="$IFS"
  IFS="|"
  
  #mainfiles="$(echo -e "$(ls -Rp "${DIRECTORY}/update/pi-apps")\n$(ls -Rp "${DIRECTORY}")" | grep -v '/' | sort | uniq | tr '\n' '|')"
  
  #list all files in update folder
  cd "${DIRECTORY}/update/pi-apps" || error "Failed to enter update directory!"
  updatefiles="$(find . -type f | cut -c 3- | grep -v '.git/' | grep -v 'apps/' | grep -v 'data/')"
  
  #list all files in main folder
  cd "${DIRECTORY}"
  localfiles="$(find . -type f | cut -c 3- | grep -v '.git/' | grep -v 'apps/' | grep -v 'data/' | grep -v 'xlunch/')"
  
  mergedfiles="$(echo -e "${localfiles}\n${updatefiles}" | sort | uniq | tr '\n' '|')"
  
  #exclude files mentioned in data/update-exclusion file
  PREIFS="$IFS"
  IFS=$'\n'                                   #exclude commented lines
  for file in $(cat data/update-exclusion | grep "^[^#;]")
  do
    mergedfiles="$(echo "$mergedfiles" | grep -v "$file")"
    echo "Excluding $file from the mergedlist."
  done
  IFS="$PREIFS" # back to IFS='|'
  
  for file in $mergedfiles
  do
    newhash=$(cat "${DIRECTORY}/update/pi-apps/${file}" 2>/dev/null | sha1sum | awk '{print $1}' | sha1sum | awk '{print $1}')
    oldhash=$(cat "${DIRECTORY}/${file}" 2>/dev/null | sha1sum | awk '{print $1}' | sha1sum | awk '{print $1}')
    #echo -e "newhash: $newhash\noldhash: $oldhash"
    
    if [ "$newhash" == "$oldhash" ];then
      echo -e "${file} is identical\e[90m to the online version. Nothing to do!\e[39m"
    else
      if [ ! -f "${DIRECTORY}/${file}" ];then
        echo -e "\e[97m${file} does not exist locally.\e[39m Adding to updatable list."
        #in this case, add to updatable list
        mainupdate="${mainupdate}|${file}"
      elif [ ! -f "${DIRECTORY}/update/pi-apps/${file}" ];then
        echo -e "\e[97m${file} only exists locally.\e[39m Will not add to updatable list."
        #in this case, do not add to updatable list
      else
        echo -e "\e[97m${file} exists in both locations, but online version is newer\e[39m. Adding to updatable list."
        #in this case, add to updatable list
        mainupdate="${mainupdate}|${file}"
      fi
      
    fi
  done
  IFS="$PREIFS"
  
  #remove initial '|' character
  mainupdate="${mainupdate:1}"
else
  error "${DIRECTORY}/update does not exist. Most likely there is no Internet connection."
fi

LIST=''

PREIFS="$IFS"
IFS="|"
for i in $updatable
do
  LIST="${LIST}${DIRECTORY}/update/pi-apps/apps/${i}/icon-24.png
$i "\("$([ $(cat "${DIRECTORY}/data/update-status/${i}") == 'new' ]&&echo 'new ')app"\)"
"
done
for i in $mainupdate
do
  LIST="${LIST}$(if [ "$(file -b --mime-type "${DIRECTORY}/${i}")" == 'text/x-shellscript' ];then
  #if updatable file in question is a shell script, then display shellscript icon.
  echo "${DIRECTORY}/icons/shellscript.png"
else
  #otherwise display txt icon.
  echo "${DIRECTORY}/icons/txt.png"
fi)
$i "\("file"\)"
"
done
IFS="$PREIFS"

if [ -z "$LIST" ];then
  echo -e '\e[92mNothing to update. Nothing to do!\e[39m'
  exit 0
fi
LIST="${LIST::-1}"
#echo "List: ${LIST}EOL"

screen_width="$(xrandr | grep "HDMI-1" | awk '{print $4}' | tr 'x+' ' ' | awk '{print $1}')"
screen_height="$(xrandr | grep "HDMI-1" | awk '{print $4}' | tr 'x+' ' ' | awk '{print $2}')"

yad --form --text='Pi-Apps updates available.' \
  --on-top --skip-taskbar --undecorated --close-on-unfocus \
  --geometry=260+$((screen_width-262))+$((screen_height-150)) \
  --image="${DIRECTORY}/icons/logo-64.png" \
  --button="Details!${DIRECTORY}/icons/info.png":0 --button="Close!${DIRECTORY}/icons/exit.png":1 || exit 0

echo -e "$LIST" | yad --center --title='Pi-Apps' --width=310 --height=300 --no-headers \
  --list --separator='\n' --window-icon="${DIRECTORY}/icons/logo.png" \
  --text='Updates available:' \
  --column=:IMG --column=Name \
  --button='Later'!"${DIRECTORY}/icons/exit.png"!"Remind me later":1 \
  --button='Update now'!"${DIRECTORY}/icons/download.png":0 || exit 0

PREIFS="$IFS"
IFS="|"
for i in $mainupdate
do
  mkdir -p "$(dirname "${DIRECTORY}/${i}")"
  
  #copy new version to apps/
  cp -f "${DIRECTORY}/update/pi-apps/${i}" "${DIRECTORY}/${i}" || echo "\e[91mFailed to copy ${DIRECTORY}/update/pi-apps/${i}\e[39m!"
  
  echo -e "\e[92m${i} was updated successfully.\e[39m"
done
IFS="$PREIFS"
if [ ! -z "$updatable" ];then
  "${DIRECTORY}/etc/terminal-run" '
    DIRECTORY="'"$DIRECTORY"'"
    updatable="'"$updatable"'"
    trap "sleep 10" EXIT
    PREIFS="$IFS"
    IFS="|"
    for i in $updatable
    do
      "${DIRECTORY}/manage" update "$i" nofetch
      echo -e "\e[92m${i} was updated successfully.\e[39m"
    done
    IFS="$PREIFS"
    echo -e "\e[92mAll updates complete. Closing in 10 seconds.\e[39m"
  ' 'Updating apps...'
fi
#.git folder
#move old .git folder to trash
gio trash "${DIRECTORY}/.git" 2>/dev/null
cp -rf "${DIRECTORY}/update/pi-apps/.git" "${DIRECTORY}/.git" || error "Failed to copy new .git!"

sleep 1
while ps -C manage &>/dev/null
do
  sleep 0.1
done

yad --text="Updates complete.
Please close all instances of Pi-Apps to apply the update." \
  --text-align=center --center --title='Pi-Apps update complete' --window-icon="${DIRECTORY}/icons/logo.png" \
  --button=OK!"${DIRECTORY}/icons/check.png":0
exit 0
