#!/bin/bash
# shellcheck disable=SC2015
set -e

VERSION_FLAG=7

emergency_hotfix() {
	local HOTFIX_VERSION_CHECK

	# Check https://garudalinux.org/os/garuda-update/hotfix-check
	if ! HOTFIX_VERSION_CHECK="$(wget --timeout=15 -qO- https://garudalinux.org/os/garuda-update/hotfix-check)" || [[ ! "$HOTFIX_VERSION_CHECK" =~ ^[0-9]+$ ]]; then
		return
	fi

	# Check if VERSION_FLAG is lower than the hotfix version
	if (( VERSION_FLAG >= HOTFIX_VERSION_CHECK )); then
		return
	fi

	local HOTFIX
	if ! HOTFIX="$(wget --timeout=15 -qO- https://garudalinux.org/os/garuda-update/hotfix)" || [[ "${HOTFIX%%$'\n'*}" != "# GARUDA UPDATE HOTFIX" ]]; then
		return
	fi

	$INT || return

	local choice
	echo -e "\n\033[1;33mUnable to perform a self-update to the latest version of garuda-update.\033[0m"
	echo -e "\033[1;34mThe Garuda Linux development team has flagged this version of garuda-update as needing outside assistance to initiate a system update.\033[0m"
	echo -e "\033[1;34mTo successfully update the system, it may be necessary to execute the Garuda Linux development team recommended hotfix script from the internet.\033[0m"
	while true; do
		echo -e "\033[1;32mDo you want to run the hotfix script now? (y/n/p = show script) \033[0m"
		read -r choice
		$INT || return
		case $choice in
			y|Y) break ;;
			n|N) return ;;
			p|P) echo "$HOTFIX" ;;
			*) echo "Invalid choice. Please enter y, n, or p." ;;
		esac
	done
	local retcode=0
	VERSION=${VERSION_FLAG} bash <<< "$HOTFIX"
	retcode=$?
	if (( retcode != 0 )); then
		exit $retcode
	else
		exec /usr/bin/garuda-update "$@"
	fi
}

self_update() {
	if [ -v SELF_UPDATE_FAIL ]; then
		unset SELF_UPDATE_FAIL
	fi
	# Let the update script self update
	if [ "$DATABASE_UPDATED" == "force" ]; then
		$PACMAN -Syy && DATABASE_UPDATED=true || true
	elif [ "$DATABASE_UPDATED" != "true" ]; then
		$PACMAN -Sy && DATABASE_UPDATED=true || true
	fi
	if [ "$DATABASE_UPDATED" != "true" ]; then
		SELF_UPDATE_FAIL=1
		return
	fi
	$INT
	if $PACMAN -Qu garuda-update &>/dev/null; then
		if SNAP_PAC_SKIP=y SKIP_AUTOSNAP='' $PACMAN -Sdd garuda-update --needed --noconfirm; then
			GARUDA_UPDATE_SELFUPDATE="$VERSION_FLAG" exec /usr/bin/garuda-update "$@"
		else
			SELF_UPDATE_FAIL=1
		fi
		$INT
	fi
	# Check if we have received sigint and should exit
	$INT
}

# Some funny stuff with reflector makes it not exit on sigint, we set up our own sigint handler for that
INT=true
trap "INT=false" INT

# Show a help text in case it was requested
if [ "$1" == "-h" ] || [ "$1" == "--help" ] || [ "$1" == "help" ]; then
	# shellcheck source=./help
	source /usr/lib/garuda/garuda-update/help
fi

# Elevate once and stop asking for the password constantly
# It would be possible to add systemd-inhibit here, but that would prevent a self-update from removing the inhibit in the future in case there is an issue.
# The performance impact of not immediately using systemd-inhibit is negligible.
if [[ $EUID -ne 0 ]]; then
	exec sudo --preserve-env="SKIP_MIRRORLIST,UPDATE_AUR,PACMAN_EXE,GARUDA_SNAPSHOT_PACMAN,PACMAN_EXTRA_OPTS" /usr/bin/garuda-update "$@"
	exit 1
fi

# Run the "I'm too lazy to fix it myself all in one" script
if [ "$1" == "remote" ]; then
	exec bash -c "VERSION=${VERSION_FLAG} . <(wget -qO- https://garudalinux.org/os/garuda-update/remote-update) \"\$@\"" remote-update "${@:2}"
fi

if [ -n "$PACMAN_EXE" ]; then
	PACMAN="$PACMAN_EXE"
else
	PACMAN="pacman"
fi

export PACMAN

DATABASE_UPDATED=false
if [ -n "$GARUDA_UPDATE_SELFUPDATE" ]; then
	DATABASE_UPDATED=true
fi

if [ ! -v GARUDA_SLEEP_INHIBIT ]; then
	self_update "$@"

	if [ -v SELF_UPDATE_FAIL ]; then
		emergency_hotfix "$@"
	fi

	if [ -x /usr/bin/systemd-inhibit ]; then
		GARUDA_SLEEP_INHIBIT=1 exec systemd-inhibit --who="Garuda Update" --why="Performing a system update with garuda-update" \
			/usr/bin/garuda-update "$@"
	fi
fi

# shellcheck source=main-update
source /usr/lib/garuda/garuda-update/main-update
