#!/bin/sh
# fix-limine-uki-entry.sh — idempotent. REQUIRES ROOT.
#
# With ENABLE_UKI=yes, limine removes /boot/vmlinuz-linux and
# /boot/initramfs-linux.img (UKI-only), but the installer-seeded first entry
# "/NoSignal (Arch Linux)" in limine.conf still uses `protocol: linux` ->
# boot():/vmlinuz-linux. That entry is the default auto-boot target and now
# dead-boots to a TTY. This converts it to a `protocol: efi` entry that boots
# the UKI, keeping the same label (so it stays first = default) and cmdline.
#
# Idempotent: if the entry is already protocol:efi (no vmlinuz path), it's a
# no-op. Always backs up limine.conf first. Refuses if the UKI is missing.
#
# NOTE: the durable fix belongs in the ISO installer's seeded limine.conf /
# limine config — see README. This repairs an already-installed system.
set -eu

ESP_PATH=/boot
UKI_NAME=nosignal
[ -r /etc/default/limine ] && . /etc/default/limine 2>/dev/null || true
[ -n "${ESP_PATH:-}" ] || ESP_PATH=/boot
[ -n "${CUSTOM_UKI_NAME:-}" ] && UKI_NAME="$CUSTOM_UKI_NAME"

CONF="$ESP_PATH/limine.conf"
UKI_REL="/EFI/Linux/${UKI_NAME}_linux.efi"
UKI_ABS="$ESP_PATH$UKI_REL"

[ "$(id -u)" -eq 0 ] || { echo "must run as root (edits $CONF)" >&2; exit 1; }
[ -f "$CONF" ]    || { echo "no $CONF" >&2; exit 1; }
[ -f "$UKI_ABS" ] || { echo "UKI not found at $UKI_ABS — aborting (won't point at a missing file)" >&2; exit 1; }

# Already fixed? (the seeded entry no longer references vmlinuz)
if ! grep -q 'path: boot():/vmlinuz-linux' "$CONF"; then
  echo "limine.conf has no dead vmlinuz entry — nothing to do"
  exit 0
fi

cp -a "$CONF" "$CONF.bak.$(date +%Y%m%d%H%M%S)"

# Rewrite ONLY the manual entry's body: protocol:linux + vmlinuz + module_path
# lines become protocol:efi + UKI path. Keeps the `cmdline:` line as-is.
awk -v uki="$UKI_REL" '
  /^\/NoSignal \(Arch Linux\)/ { print; inblk=1; next }
  inblk && /^[^[:space:]]/      { inblk=0 }            # next top-level entry ends the block
  inblk && /^[[:space:]]*protocol:[[:space:]]*linux/ { print "    protocol: efi"; next }
  inblk && /^[[:space:]]*path:[[:space:]]*boot\(\):\/vmlinuz-linux/ { print "    path: boot():" uki; next }
  inblk && /^[[:space:]]*module_path:/ { next }        # drop ucode/initramfs modules (UKI is self-contained)
  { print }
' "$CONF" > "$CONF.tmp"

# sanity: must still contain our UKI path and no vmlinuz path
grep -q "path: boot():$UKI_REL" "$CONF.tmp" && ! grep -q 'boot():/vmlinuz-linux' "$CONF.tmp" \
  || { echo "rewrite sanity check failed — leaving $CONF untouched" >&2; rm -f "$CONF.tmp"; exit 1; }

mv "$CONF.tmp" "$CONF"
sync
echo "fixed: '/NoSignal (Arch Linux)' now protocol:efi -> $UKI_REL (backup kept)"
