#!/bin/bash
VERSION=$(dpkg-query -W -f='${Version}' mw-pxeboot 2>/dev/null || echo "unknown")

usage() {
  cat <<'EOF'
Usage: mw-pxeboot [OPTIONS]

Set the next boot to PXE and reboot (default action). Always asks for
confirmation first unless --force is given -- this reboots the host
into network install, which will wipe and reinstall it.

Options:
  -h, --help          Show this help and exit
  -v, --version       Show version and exit
  --purge-non-pxe     Additionally delete all UEFI NVRAM boot entries
                      except the detected PXE/network boot entry before
                      rebooting. The confirmation prompt lists exactly
                      what will be deleted. Does not reboot at all if
                      any entry failed to delete.
  --force             Skip the confirmation prompt

Examples:
  mw-pxeboot                  Confirm, then set next boot to PXE and reboot
  mw-pxeboot --purge-non-pxe  Confirm, then also remove stale non-PXE
                               UEFI NVRAM boot entries before rebooting
EOF
}

FORCE=0
ACTION="boot-pxe"

for arg in "$@"; do
  case "$arg" in
    -h|--help)
      usage
      exit 0
      ;;
    -v|--version|version)
      echo "mw-pxeboot $VERSION"
      exit 0
      ;;
    --purge-non-pxe)
      ACTION="purge-non-pxe"
      ;;
    --force)
      FORCE=1
      ;;
    *)
      echo "Error: unknown option '$arg'" >&2
      usage >&2
      exit 1
      ;;
  esac
done

[ "$EUID" -ne 0 ] && { echo "Error: Must run as root"; exit 1; }

confirm() {
  local prompt="$1"
  if [ "$FORCE" -eq 1 ]; then
    return 0
  fi
  if [ ! -t 0 ]; then
    echo "Error: confirmation required but no interactive terminal available. Re-run with --force." >&2
    exit 1
  fi
  read -r -p "$prompt [y/N] " reply
  case "$reply" in
    [yY]|[yY][eE][sS]) return 0 ;;
    *) echo "Aborted."; exit 1 ;;
  esac
}

find_pxe_bootnum() {
  local pxe
  pxe=$(efibootmgr | grep -i "ip4" | head -1 | sed 's/Boot\([0-9A-F]*\).*/\1/')
  [ -z "$pxe" ] && pxe=$(efibootmgr | grep -iE "network|pxe|ip6|gbe|ethernet" | head -1 | sed 's/Boot\([0-9A-F]*\).*/\1/')
  echo "$pxe"
}

do_boot_pxe() {
  echo "Setting next boot to PXE..."
  if ipmitool chassis bootdev pxe options=efiboot >/dev/null 2>&1; then
    echo "Next boot: PXE"
    sleep 2
    reboot -f
  elif command -v efibootmgr >/dev/null 2>&1; then
    local pxe
    pxe=$(find_pxe_bootnum)
    if [ -n "$pxe" ]; then
      efibootmgr --bootnext "$pxe" && echo "Next boot: PXE (Boot$pxe)" && sleep 2 && reboot -f
    else
      echo "Error: No PXE entry found"
      exit 1
    fi
  else
    echo "Error: No supported method (ipmitool/efibootmgr)"
    exit 1
  fi
}

case "$ACTION" in
  purge-non-pxe)
    command -v efibootmgr >/dev/null 2>&1 || { echo "Error: efibootmgr not available"; exit 1; }
    PXE=$(find_pxe_bootnum)
    if [ -z "$PXE" ]; then
      echo "Error: No PXE entry found -- refusing to purge (would leave no PXE fallback)"
      exit 1
    fi
    mapfile -t OTHERS < <(efibootmgr | grep -E '^Boot[0-9A-F]{4}' | sed 's/^Boot\([0-9A-F]*\).*/\1/' | grep -v "^${PXE}$")
    if [ "${#OTHERS[@]}" -eq 0 ]; then
      echo "No non-PXE NVRAM boot entries found."
      exit 0
    fi
    echo "PXE boot entry: Boot${PXE} (will be kept)"
    echo "The following non-PXE NVRAM boot entries will be deleted, then the host will reboot to PXE:"
    for b in "${OTHERS[@]}"; do
      efibootmgr | grep "^Boot${b}"
    done
    confirm "Delete these ${#OTHERS[@]} non-PXE NVRAM boot entries and reboot to PXE?"
    FAILED=0
    for b in "${OTHERS[@]}"; do
      if efibootmgr -b "$b" -B >/dev/null 2>&1; then
        echo "Deleted Boot${b}"
      else
        echo "Failed to delete Boot${b} (still referenced in BootOrder, or firmware refused the delete)" >&2
        FAILED=1
      fi
    done
    if [ "$FAILED" -eq 1 ]; then
      echo "Some entries could not be deleted via the standard efibootmgr method." >&2
      echo "Certain firmware (observed on brix2, AMI UEFI) refuses to delete a Boot#### entry" >&2
      echo "still listed in BootOrder, and some entries need to be rewritten before a delete" >&2
      echo "is accepted. That workaround is host/firmware-specific and is deliberately NOT" >&2
      echo "implemented here to avoid raw NVRAM writes running unreviewed on other hardware" >&2
      echo "(e.g. r730). See pxeboot's brix2/user-data early-commands for the known-working" >&2
      echo "technique if this needs to be applied post-install." >&2
      echo "Not rebooting -- purge did not fully succeed." >&2
      exit 1
    fi
    echo "All non-PXE entries deleted successfully."
    do_boot_pxe
    ;;
  boot-pxe)
    confirm "Reboot now to set next boot to PXE? This will wipe and reinstall the host."
    do_boot_pxe
    ;;
esac
