#!/bin/bash
#
#Copyright 2012 - 2017 CurlyMo, mk01 & mkreisl <development@xbian.org>
#
#This file is part of XBian - XBMC on the Raspberry Pi.
#
#XBian is free software: you can redistribute it and/or modify it under the
#terms of the GNU General Public License as published by the Free Software
#Foundation, either version 3 of the License, or (at your option) any later
#version.
#
#XBian is distributed in the hope that it will be useful, but WITHOUT ANY
#WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
#FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
#details.
#
#You should have received a copy of the GNU General Public License along
#with XBian. If not, see <http://www.gnu.org/licenses/>

#|------------------------------------|
#|          Global variables          |
#|------------------------------------|

# The arguments this module accepts
ARGUMENTS=(list progress install installtest status enableauto snapapt enablerepo distupgrade autoinventory updatedb);

#|------------------------------------|
#|          Include files             |
#|------------------------------------|

source $BASEPATH/modules/updates/functions
if [ $GUIMODE -eq 1 ]; then
	source $BASEPATH/modules/updates/dialogs
fi
source $BASEPATH/functions/packages

#|------------------------------------|
#|           Main program             |
#|------------------------------------|

# Executes the GUI version of this module
function showGUIFn() {
	if [ $REMOTEPKGDBUPDATED -eq 0 ]; then
		showDownloadPackageListDlg;
		if ! updateAptMirrorsFn; then
			showFailedToRetrieveAptMirrosDlg;
		else
			downloadPackageListFn;
			REMOTEPKGDBUPDATED=0
		fi;
	fi
	if [ "$LOCALPKGDBUPDATED" -eq 0 ]; then
		if [ "$REMOTEPKGDBUPDATED" -eq 1 ]; then
			localPackageDBOutdatedFn;
			if [ $? -eq 1 ]; then
				showUpdateAptDBDlg;
				updateAptFn;
				if [ $? -eq 1 ]; then
					LOCALPKGDBUPDATED=1;
				else
					showUpdateAptDBFailedDlg;
				fi
			fi
		fi
	fi
	if [ "$APTUPDATELISTUPDATED" -eq 0 ] || [ ! -f "/tmp/aptupdates" ]; then
		showRetrievingUpdateListDlg;
		FORCE=yes retrieveUpdateListFn;
		APTUPDATELISTUPDATED=1;
	fi
	# getAllUpdatesLisFn # currently useless bc  calls getAllPackagesLisFn only
	getAllPackagesLisFn
	SYSTEMUPDATE=0;

	if [ ${#UPDATES[@]} -ge 1 ]; then

		showSystemUpdateConfirmDlg;
		if [ $? -eq 0 ]; then
			showUpgradeSystemDlg;
			updateSystemFn 1 "${UPDATES[*]}";
			STATUS=$?;
			LOG=0;
			if [ $STATUS -eq 1 ]; then
				showUpdateAlreadyInstalledDlg;
			elif [ $STATUS -eq 2 ]; then
				showUpdateVersionNotExistDlg;
			elif [ $STATUS -eq 3 ]; then
				showUpdateNotExistsDlg;
			elif [ $STATUS -eq 4 ]; then
				showUpdateDowngradeDlg;
			elif [ $STATUS -ge 5 ]; then
				showUpdateAdvErrorDlg;
			elif [ $STATUS -eq 0 ]; then
				updateSystemFn 0 "${UPDATES[*]}";
				if [ $? -eq 0 ]; then
					if [ -f "/tmp/aptstatus" ] || [ -f "/home/xbian/update" ]; then
						showAskForLogDlg;
						if [ $? -eq 0 ]; then
							if [ -f "/home/xbian/xbian-update.log" ]; then
								showSystemUpdateLogDlg;
							elif [ -f "/tmp/aptstatus" ]; then
								showUpdateLogDlg;
							fi
						fi
					fi
					[ -e /tmp/aptstatus ] && rm /tmp/aptstatus
					LOG=1;
					if [ ! -e /run/noreboot ]; then
					    showSystemUpdateRebootDlg;
					    sleep 10; sudo reboot;
					fi
				else
					showUpdateAdvErrorDlg;
				fi
			fi
			if [ $LOG -eq 0 ]; then
				showAskForLogDlg;
				if [ $? -eq 0 ]; then
					showUpdateLogDlg;
				fi
			fi
			SYSTEMUPDATE=1;
		fi
	fi
	if [ $SYSTEMUPDATE -eq 0 ]; then
		if [ ${#PACKAGES[@]} -eq 0 ]; then
			showUpToDateDlg;
			[ -e /tmp/aptstatus ] && rm /tmp/aptstatus
		else
			showAvailableUpdatesDlg "${PACKAGES[*]}";
			if [ $? -eq 0 ]; then
				IFS=" ";
				SELECTION=($RETURN);
				showInstallUpdatesDlg;
				updatePackagesFn 1 "${SELECTION[*]}";
				STATUS=$?;
				if [ $STATUS -eq 1 ]; then
					showUpdateAlreadyInstalledDlg;
				elif [ $STATUS -eq 2 ]; then
					showUpdateVersionNotExistDlg;
				elif [ $STATUS -eq 3 ]; then
					showUpdateNotExistsDlg;
				elif [ $STATUS -eq 4 ]; then
					showUpdateDowngradeDlg;
				elif [ $STATUS -ge 5 ]; then
					showUpdateAdvErrorDlg;
				elif [ $STATUS -eq 0 ]; then
					updatePackagesFn 0 "${SELECTION[*]}";
				fi
				if [ -f "/tmp/aptstatus" ]; then
					showAskForLogDlg;
					if [ $? -eq 0 ]; then
						showUpdateLogDlg;
					fi
				fi
				[ -e /tmp/aptstatus ] && rm /tmp/aptstatus

				APTUPDATELISTUPDATED=0
				showGUIFn;
			fi
		fi
	fi
	APTUPDATELISTUPDATED=0
}

# Executes the command line version of this module
#  $1 Argument [String]
# list | installtest | install
#  $2 Type [String] packages | upgrades
# install | installtest
#  $@ Index of upgradeable packages
# Returns
# list | installtest | install
#  -  1: Success
#  -  0: Failed
#  - -1: Wrong number of arguments
#  - -2: No updates available
#  - -3: You need to run an updatedb first
#  *list
#  -  [index];[package name];[install version];[available version]
#  *installtest | install - (Simulates an) apt-get install
#  -  1: Package can be installed without problems
#  -  2: This package is already installed
#  -  3: Package not found in apt repository
#  -  4: A newer version of this package is already installed
#  -  5: There is a size mismatch for the remote package
#  -  6: The package itself got an internal error
#  *progress
#  -  1: Apt is still running
#  -  0: Apt is not running
#  *updatedb - Updates local and remote apt library (when needed)
#  *enableauto - enable automatic updates
#  -     no parameter - get actual settings
#  -  1: is enabled or set requested action was success
#  -  0: is disabled or set requested action was failure

function showCMDFn() {
	case $1 in
		autoinventory)
			setEnableInventoryAuto $2 $3; rc=$?
			if [ $rc -gt 0 ]; then
			    [ -z "$2" ] && echo "1 $rc" || echo "$rc"
			else
			    echo "$rc 1"
			fi
			;;
		enableauto)
			setEnableAuto $2
			echo $?
			;;
		snapapt)
			setSnapApt $2
			echo $?
			;;
		enablerepo)
			setEnableRepo $2 $3
			echo $?
			;;
		distupgrade)
			if [ -x /usr/local/sbin/xbian-update-repo ]; then
				if [ $# -eq 2 ]; then
					case "$2" in
						query)   STATUS=$(/usr/local/sbin/xbian-update-repo query) ;;
						prepare) /usr/local/sbin/xbian-update-repo; apt-get update --allow-releaseinfo-change &>/tmp/aptstatus && STATUS=1 || STATUS=-2 ;;
						execute) updatePackagesFn 2 $1; STATUS=$(($?+1)); sleep 3 ;;
						finish)  rm -f /usr/local/sbin/xbian-update-repo; STATUS=1 ;;
						*)       STATUS=-3 ;;
					esac
					echo $STATUS
				else
					echo -1
				fi
			else
				echo 0
			fi
			;;
		list)
			if [ $# -eq 2 ]; then
				if [ -f "$BASEPATH/config/pkglist" ] && [ -f "$BASEPATH/config/aptmirror" ]; then
					int=$(grep "APT::Periodic::Update-Package-Lists" /etc/apt/apt.conf.d/20auto-upgrades 2>/dev/null| grep -o "[0-9]*")
					[ -z "$int" -o "$int" -eq 0 ] && int=1440 || int=$((int*24*60))
					[ -z "$(eval find /var/lib/apt/periodic/update-success-stamp -cmin -$int 2>/dev/null)" ] && { echo -3; exit 0; }
					limit=999; i=1
					[ -z "$(eval find /tmp/aptupdates -cmin -$int 2>/dev/null)" ] && retrieveUpdateListFn;
					if [ "$2" == "packages" -o "$2" == "upgrades" ]; then
						getAllPackagesLisFn;
						if [ ${#PACKAGES[@]} -ge 1 ]; then
							for KEY in ${!PACKAGES[@]}; do
								test $i -gt $limit && break
                                                                echo $(($KEY+1))";"${PACKAGES[$KEY]};
                                                                i=$(($i+1))
							done
						else
							echo -2;
						fi
					else
						echo -1;
					fi
				else
					echo -3;
				fi
			else
				echo -1;
			fi
		;;
		install|installtest)
			if [ $# -ge 3 ]; then
				[ "$1" == "install" ] && fn=2 || fn=1
				if [ -f "$BASEPATH/config/pkglist" ] && [ -f "$BASEPATH/config/aptmirror" ]; then
					shift;
					if [ "$1" == "packages" -o "$1" == "upgrades" ]; then
						shift;
						getAllPackagesLisFn;
						SELECTION=($@);
						updatePackagesFn $fn "${SELECTION[*]}"; # retval between 0 and 6
						echo $(($?+1));
					else
						echo -1;
					fi
				else
					echo -3;
				fi
			else
				echo -1;
			fi
		;;
		status)
			grep -q "^E:" /tmp/aptstatus && RESULT=-1 || RESULT=$(grep -i "newly installed" /tmp/aptstatus | awk '{ print $1+$3, $6, $10}')
			[ "$RESULT" = "" ] && RESULT=-2
			echo $RESULT
		;;
		progress)
			if [ -e /run/lock/xbian-config-updatedb ] || pgrep "apt-get|dpkg" &>/dev/null || pgrep -f "xbian-apt-show-versions" &>/dev/null; then
				echo 1;
			else
				[ x"$2" = x"lock" ] && touch /run/lock/xbian-config-updatedb
				echo 0;
			fi
		;;
		updatedb)
			updateAptMirrorsFn # retval always 0
			if (( $? == 0 )); then
				if (( $(showCMDFn progress lock) > 0 )); then
					while (( $(showCMDFn progress lock) > 0 )); do
						sleep 2
					done
				else
					updateAptFn
				fi
				retrieveUpdateListFn
				getAllPackagesLisFn
				# getAllUpdatesLisFn # currently useless bc calls getAllPackagesLisFn only
				if [ ${#PACKAGES[@]} -ge 1 -o ${#UPDATES[@]} -ge 1 ]; then
					STATUS=1;
				else
					STATUS=0;
				fi
				rm -f /run/lock/xbian-config-updatedb
			else
				STATUS=-1;
			fi
			echo $STATUS;
		;;
	esac
}
