#!/bin/sh
# /usr/sbin/jd2-tryboot-commit
#
# Promote /boot/firmware/*-candidate files to their active names. Runs only
# when the current boot is a tryboot (firmware exposes this via
# /proc/device-tree/chosen/bootloader/tryboot == 1); otherwise a no-op.
#
# Invoked by jd2-tryboot-confirm.service when /run/m50-ui/ready appears
# (the m50-ui app writes that sentinel after the main window renders).
# Also safe to run manually.

set -eu

FIRMWARE_DIR="${JD2_FIRMWARE_DIR:-/boot/firmware}"
TRYBOOT_FLAG="${JD2_TRYBOOT_FLAG:-/proc/device-tree/chosen/bootloader/tryboot}"
ACTIVE_KERNEL="${FIRMWARE_DIR}/kernel_2712_jd2.img"
ACTIVE_INITRAMFS="${FIRMWARE_DIR}/initramfs_2712_jd2"
CANDIDATE_KERNEL="${FIRMWARE_DIR}/kernel_2712_jd2-candidate.img"
CANDIDATE_INITRAMFS="${FIRMWARE_DIR}/initramfs_2712_jd2-candidate"

if [ ! -r "${TRYBOOT_FLAG}" ]; then
    exit 0
fi

# The device-tree property is a 4-byte BIG-ENDIAN integer, not ASCII: tryboot
# active is the byte sequence 00 00 00 01, never the character "1" (0x31). Read
# the raw bytes in order (od -tx1 is endianness-independent), join to a hex
# string, and parse. A blank/zero value means this boot is not a tryboot trial.
flag_hex=$(od -An -tx1 "${TRYBOOT_FLAG}" 2>/dev/null | tr -d ' \n')
[ -n "${flag_hex}" ] || exit 0
[ "$((0x${flag_hex}))" -ne 0 ] || exit 0

if [ -e "${CANDIDATE_KERNEL}" ]; then
    mv -f "${CANDIDATE_KERNEL}" "${ACTIVE_KERNEL}"
fi
if [ -e "${CANDIDATE_INITRAMFS}" ]; then
    mv -f "${CANDIDATE_INITRAMFS}" "${ACTIVE_INITRAMFS}"
fi

# The candidate is now the active kernel, so tryboot.txt (which points kernel=
# at the now-gone -candidate image) is stale. Leaving it would make a future
# tryboot load a missing kernel and halt. Drop it.
rm -f "${FIRMWARE_DIR}/tryboot.txt"

sync "${FIRMWARE_DIR}" 2>/dev/null || sync
