#!/usr/bin/env bash

## of-provision v1.01 (10th August 2026)
##  Checks for a file on /boot pointing to a hosted project or install.sh.
##  If present, downloads and runs that install.sh as the normal user. Lets
##  community repos provide their own install.sh without us having to bake
##  every combination of software into an image.
##
##  Runs once: the service disables itself as soon as it fires, regardless
##  of outcome. Re-enable with 'systemctl enable of-provision.service'.

if [ "$(id -u)" -ne 0 ]; then
	echo "You need to run this with superuser privileges. Try 'sudo $0'."
	exit 1
fi

SETUPFILE="/boot/setup.txt"
LOGFILE="/var/log/setup.log"
WORKDIR="/tmp/of-provision"
OPENFRAMEUSER="of"

log() {
	echo "$1" | tee -a "$LOGFILE"
}

[ -f "$SETUPFILE" ] || exit 0

# One-shot: disable ourselves now, before doing anything else, so we don't
# run again on next boot regardless of how this attempt turns out.
systemctl disable of-provision.service >/dev/null 2>&1

URL="$(head -n1 "$SETUPFILE" | tr -d '[:space:]')"

: > "$LOGFILE"
log "of-provision: starting at $(date -u '+%Y-%m-%d %H:%M:%S UTC')"
if [ "$(timedatectl show -p NTPSynchronized --value 2>/dev/null)" != "yes" ]; then
	log "of-provision: warning, system clock is not NTP-synchronised; HTTPS downloads below may fail on certificate checks."
fi
log "of-provision: requested source: $URL"

if [[ -z "$URL" ]]; then
	log "of-provision: setup.txt is empty. Aborting."
	mv "$SETUPFILE" "${SETUPFILE}.rejected"
	exit 1
elif [[ "$URL" =~ install\.sh$ ]]; then
	# Direct link, use as given.
	CANDIDATES=("$URL")
elif [[ "$URL" =~ ^https?://github\.com/([^/]+)/([^/]+) ]]; then
	# GitHub project URL: look for install.sh on the default branch, trying
	# 'main' then falling back to the older 'master' convention.
	OWNER="${BASH_REMATCH[1]}"
	REPO="${BASH_REMATCH[2]%.git}"
	CANDIDATES=(
		"https://raw.githubusercontent.com/${OWNER}/${REPO}/refs/heads/main/install.sh"
		"https://raw.githubusercontent.com/${OWNER}/${REPO}/refs/heads/master/install.sh"
	)
else
	# Some other project URL: look for install.sh at its root.
	CANDIDATES=("${URL%/}/install.sh")
fi

mkdir -p "$WORKDIR"
INSTALLER_PATH="${WORKDIR}/install.sh"

# network-online.target only means whatever brought it up thinks it's done;
# DHCP/DNS can still lag behind that for a few seconds, particularly over
# Wi-Fi, so retry each candidate a few times before giving up on it.
INSTALLER_URL=""
for CANDIDATE in "${CANDIDATES[@]}"; do
	log "of-provision: trying ${CANDIDATE}"
	for ATTEMPT in 1 2 3 4 5; do
		CURL_ERROR="$(curl -fSL -o "$INSTALLER_PATH" "$CANDIDATE" 2>&1 >/dev/null)" && { INSTALLER_URL="$CANDIDATE"; break; }
		log "of-provision: attempt ${ATTEMPT} failed: ${CURL_ERROR}"
		sleep 5
	done
	[ -n "$INSTALLER_URL" ] && break
done

if [ -z "$INSTALLER_URL" ]; then
	log "of-provision: failed to download install.sh. Aborting."
	mv "$SETUPFILE" "${SETUPFILE}.failed"
	exit 1
fi

log "of-provision: fetched ${INSTALLER_URL}"

chmod +x "$INSTALLER_PATH"
chown "$OPENFRAMEUSER:$OPENFRAMEUSER" "$INSTALLER_PATH"

log "of-provision: running installer as '${OPENFRAMEUSER}'..."
echo >> "$LOGFILE"

su - "$OPENFRAMEUSER" -c "$INSTALLER_PATH" 2>&1 | tee -a "$LOGFILE"
INSTALLER_RESULT="${PIPESTATUS[0]}"

if [ "$INSTALLER_RESULT" -eq 0 ]; then
	echo >> "$LOGFILE"
	log "of-provision: installer completed successfully."
	rm "$SETUPFILE"
else
	echo >> "$LOGFILE"
	log "of-provision: installer exited with an error. See above."
	mv "$SETUPFILE" "${SETUPFILE}.failed"
fi

rm -rf "$WORKDIR"

log "of-provision: rebooting..."
sync
systemctl reboot

exit 0
