#!/bin/sh
# Rescue script: set EEPROM boot order directly from the initramfs (no chroot needed).
# Uses rpi-eeprom-config + pieeprom.bin bundled in the Alpine-based initramfs.
# Sets BOOT_ORDER=0xf21 (eMMC first, then network, restart) with fast network timeouts.
# Run from the initramfs rescue shell (after booting with provisioning_rescue=1 in cmdline).
# Pass --edit to open the editor manually instead of applying automatically.

set -e
EEPROM_FW="/lib/firmware/raspberrypi/bootloader/default/pieeprom.bin"
BOOT_MNT="/mnt/boot"
MANUAL=0
[ "$1" = "--edit" ] && MANUAL=1

# Clean up any previous mounts
umount "$BOOT_MNT" 2>/dev/null || true
umount /mnt/emmc 2>/dev/null || true

# --- Read current EEPROM config ---
echo "=== EEPROM rescue (Alpine initramfs) ==="

if ! command -v rpi-eeprom-config >/dev/null 2>&1; then
  echo "ERROR: rpi-eeprom-config not found in initramfs."
  echo "This initramfs was not built with the Alpine build script."
  exit 1
fi

if [ ! -f "$EEPROM_FW" ]; then
  echo "ERROR: EEPROM firmware not found at $EEPROM_FW"
  echo "Rebuild the initramfs with build.sh to include it."
  exit 1
fi

echo "Reading current EEPROM config from running bootloader..."
CURRENT_CONF="/tmp/eeprom-current.conf"
rpi-eeprom-config 2>/dev/null > "$CURRENT_CONF" || true

if [ ! -s "$CURRENT_CONF" ]; then
  echo "Could not read current EEPROM config via vcgencmd."
  echo "Extracting config from firmware image instead..."
  rpi-eeprom-config "$EEPROM_FW" > "$CURRENT_CONF" 2>/dev/null || true
fi

if [ ! -s "$CURRENT_CONF" ]; then
  echo "ERROR: Could not read EEPROM config from either source."
  exit 1
fi

echo "Current config:"
cat "$CURRENT_CONF"
echo ""

# --- Manual mode: mount eMMC boot, chroot, edit ---
if [ "$MANUAL" -eq 1 ]; then
  echo "Manual mode: mounting eMMC for interactive editing..."
  mkdir -p /mnt/emmc
  mount /dev/mmcblk0p2 /mnt/emmc 2>/dev/null || true
  BOOT="/mnt/emmc/boot/firmware"
  [ ! -d "$BOOT" ] && BOOT="/mnt/emmc/boot"
  if [ -b /dev/mmcblk0p1 ]; then
    mkdir -p "$BOOT"
    mount /dev/mmcblk0p1 "$BOOT" 2>/dev/null || true
  fi
  mount -t proc none /mnt/emmc/proc 2>/dev/null || true
  mount -t sysfs none /mnt/emmc/sys 2>/dev/null || true
  mount --bind /dev /mnt/emmc/dev 2>/dev/null || true
  if [ -x /mnt/emmc/usr/bin/rpi-eeprom-config ]; then
    chroot /mnt/emmc /usr/bin/rpi-eeprom-config --edit
  else
    echo "rpi-eeprom-config not found on eMMC. Dropping to shell."
    chroot /mnt/emmc /bin/sh -i
  fi
  exit 0
fi

# --- Automatic mode: build new config and apply ---
NEW_CONF="/tmp/eeprom-new.conf"

# Keep settings we don't modify, strip the ones we replace
grep -v '^BOOT_ORDER=' "$CURRENT_CONF" \
  | grep -v '^NET_BOOT_MAX_RETRIES=' \
  | grep -v '^DHCP_TIMEOUT=' \
  | grep -v '^DHCP_REQ_TIMEOUT=' \
  | grep -v '^TFTP_IP=' \
  | grep -v '^NET_INSTALL_AT_POWER_ON=' \
  > "$NEW_CONF" || true

echo 'BOOT_ORDER=0xf21' >> "$NEW_CONF"
echo 'NET_BOOT_MAX_RETRIES=3' >> "$NEW_CONF"
echo 'DHCP_TIMEOUT=1500' >> "$NEW_CONF"
echo 'DHCP_REQ_TIMEOUT=500' >> "$NEW_CONF"
echo 'NET_INSTALL_AT_POWER_ON=0' >> "$NEW_CONF"

echo "New config to apply:"
cat "$NEW_CONF"
echo ""

# Create the modified EEPROM image with the new config embedded
EEPROM_OUT="/tmp/pieeprom.upd"
echo "Embedding config into EEPROM firmware image..."
rpi-eeprom-config --config "$NEW_CONF" --out "$EEPROM_OUT" "$EEPROM_FW"

if [ ! -f "$EEPROM_OUT" ] || [ ! -s "$EEPROM_OUT" ]; then
  echo "ERROR: Failed to create modified EEPROM image."
  exit 1
fi

# Generate the signature file (sha256 of the .upd, named .sig)
EEPROM_SIG="/tmp/pieeprom.sig"
sha256sum "$EEPROM_OUT" | awk '{print $1}' > "$EEPROM_SIG"

# Mount eMMC boot partition and copy the update files
echo "Mounting eMMC boot partition..."
if [ ! -b /dev/mmcblk0p1 ]; then
  echo "ERROR: /dev/mmcblk0p1 not found. Is eMMC present?"
  exit 1
fi

mkdir -p "$BOOT_MNT"
mount /dev/mmcblk0p1 "$BOOT_MNT" || { echo "ERROR: Could not mount boot partition"; exit 1; }

cp "$EEPROM_OUT" "$BOOT_MNT/pieeprom.upd"
cp "$EEPROM_SIG" "$BOOT_MNT/pieeprom.sig"
sync

echo ""
echo "=== EEPROM update written to eMMC boot partition ==="
echo "  BOOT_ORDER=0xf21 (eMMC first, then network, restart)"
echo "  NET_BOOT_MAX_RETRIES=3, DHCP_TIMEOUT=1500ms"
echo "  Files: pieeprom.upd + pieeprom.sig on /dev/mmcblk0p1"
echo ""
echo "The bootloader will apply this update on next boot from eMMC."
echo ""
echo "Next steps:"
echo "  1. Disable network boot on the LXC (so next boot falls through to eMMC)"
echo "  2. Reboot: reboot -f  (or: echo b > /proc/sysrq-trigger)"

umount "$BOOT_MNT" 2>/dev/null || true
rm -f "$CURRENT_CONF" "$NEW_CONF" "$EEPROM_OUT" "$EEPROM_SIG"
