#!/bin/sh

# (C) 2017-2025 by Christian Hesse <mail@eworm.de>
#
# This program 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.

set -e

function help() {
	echo "usage: ${0} [OPTIONS]"
	echo
	echo ' -a  abort pending system-update'
	echo ' -c  clean before download'
	echo ' -f  force if other system-update is pending'
	echo ' -h  this help'
	echo ' -p  reboot, install and poweroff immediately'
	echo ' -r  reboot and install immediately'
	echo ' -t  start timer for nightly reboot'
	echo ' -y  update sync databases'
}

CLEAN=0
POWEROFF=0
REBOOT=0
TIMER=0

while getopts 'acfhprty' opt; do
	case ${opt} in
		h)
			help
			exit 0
			;;
		a|c|f|p|r|t|y)
			;;
		*)
			exit 1
			;;
	esac
done

if systemd-detect-virt --chroot 2>/dev/null; then
	echo 'Running in chroot, skipping.' >&2
	exit 0
fi

if [ ! -d /run/systemd/system ]; then
	echo 'Current root is not booted, skipping.' >&2
	exit 0
fi

if [ "${UID}" -ne 0 ]; then
	if command -v pkexec >/dev/null; then
		echo 'Missing privileges, trying to elevate.' >&2
		exec pkexec "${0}" "${@}"
	fi

	echo "You need elevated privileges. Please run as user 'root'!" >&2
	exit 1
fi

OPTIND=1
while getopts 'acfhprty' opt; do
	case ${opt} in
		a)
			rm --force \
				/system-update \
				/run/systemd/system/systemd-poweroff.service \
				/run/systemd/system/systemd-reboot.service
			systemctl daemon-reload
			exit 0
			;;
		c)
			if pacman-conf 'CleanMethod' | grep -q 'KeepCurrent'; then
				CLEAN=1
			else
				echo 'The clean method is not set to keep current. Not cleaning.' >&2
			fi
			;;
		f)
			rm -f /system-update
			;;
		p)
			POWEROFF=1
			REBOOT=1
			;;
		r)
			REBOOT=1
			;;
		t)
			TIMER=1
			;;
		y)
			pacman --sync --refresh
			;;
	esac
done

# make sure no other update is pending
if [ -e '/system-update' -a "$(readlink '/system-update')" != '/var/cache/pacman/pkg' ]; then
	echo 'Another update is pending.' >&2
	exit 1
fi

# exclude /etc/pacman.d/offline.conf
function finish { rm -f /run/pacman.conf; }
trap finish EXIT
sed \
	-e '/^Include *= *\/etc\/pacman\.d\/offline\.conf$/s|^|#|' \
	-e '/^#Include *= *\/etc\/pacman\.d\/offline-include\.conf$/s|^#||' \
	< /etc/pacman.conf > /run/pacman.conf

# remove the symlink for now, will be recreated it later
rm -f /system-update

# check for available updates
if [ "$(pacman --config /run/pacman.conf --sync --sysupgrade --print | wc -l)" -eq 0 ]; then
	echo "No updates available."
	exit 0
fi

# clean cache
if [ ${CLEAN} -eq 1 ]; then
	pacman --sync --noconfirm --clean
fi

# download packages
pacman --config /run/pacman.conf --sync --noconfirm --sysupgrade --downloadonly

# enable system update
ln -sf /var/cache/pacman/pkg /system-update
if [ ${POWEROFF} -eq 1 ]; then
	touch /run/pacman-offline-poweroff
fi

# force a soft-reboot on (manual) reboot ...
ln -sf ../../../usr/lib/systemd/system/systemd-soft-reboot.service \
	/run/systemd/system/systemd-reboot.service

# ... and also on poweroff, but prepare poweroff
cp /usr/lib/systemd/system/systemd-soft-reboot.service \
	/run/systemd/system/systemd-poweroff.service
cat >> /run/systemd/system/systemd-poweroff.service <<-EOF

	[Service]
	ExecStart=/usr/bin/touch /run/pacman-offline-poweroff
	EOF

# reload for service changes
systemctl daemon-reload

# (soft-)reboot if requested
if [ ${REBOOT} -eq 1 ]; then
	echo 'Rebooting for update.'
	exec systemctl reboot
fi

# start timer if requested
if [ ${TIMER} -eq 1 ]; then
	systemctl start pacman-offline-reboot.timer
fi

# show the timer (if active)
systemctl --quiet --no-pager list-timers \
	pacman-offline-prepare.timer \
	pacman-offline-reboot.timer
