#!/usr/bin/env bash
# disable-grub-countdown.sh — Show the GRUB dual-boot menu without a countdown.

set -euo pipefail
IFS=$'\n\t'

readonly SCRIPT_NAME="${0##*/}"
readonly GRUB_DEFAULTS="/etc/default/grub"
DRY_RUN=0

usage() {
  cat <<EOF
Usage: $SCRIPT_NAME [--dry-run] [--help]

Configures GRUB to show the boot menu and wait indefinitely:

  GRUB_TIMEOUT_STYLE=menu
  GRUB_TIMEOUT=-1

Options:
  --dry-run    Print actions without executing.
  --help, -h   Show this help.
EOF
}

log() { printf '\033[1;34m[%s]\033[0m %s\n' "${SCRIPT_NAME%.sh}" "$*"; }
die() { printf '\033[1;31m[%s] ERROR:\033[0m %s\n' "${SCRIPT_NAME%.sh}" "$*" >&2; exit 1; }

while (( $# )); do
  case "$1" in
    --dry-run) DRY_RUN=1 ;;
    -h|--help) usage; exit 0 ;;
    *) die "Unknown argument: $1 (try --help)" ;;
  esac
  shift
done

(( EUID == 0 )) || die "Please run as root: sudo bash $SCRIPT_NAME"
[[ -f "$GRUB_DEFAULTS" ]] || die "Missing $GRUB_DEFAULTS. This system does not look like a GRUB-based Ubuntu/Debian install."

for tool in cp date grep mktemp sed; do
  command -v "$tool" >/dev/null 2>&1 || die "Missing required tool: $tool"
done

if command -v update-grub >/dev/null 2>&1; then
  GRUB_UPDATE_CMD=(update-grub)
elif command -v grub-mkconfig >/dev/null 2>&1; then
  GRUB_UPDATE_CMD=(grub-mkconfig -o /boot/grub/grub.cfg)
elif command -v grub2-mkconfig >/dev/null 2>&1; then
  if [[ -d /boot/grub2 ]]; then
    GRUB_UPDATE_CMD=(grub2-mkconfig -o /boot/grub2/grub.cfg)
  else
    GRUB_UPDATE_CMD=(grub2-mkconfig -o /boot/grub/grub.cfg)
  fi
else
  die "Could not find update-grub, grub-mkconfig, or grub2-mkconfig."
fi

BACKUP="${GRUB_DEFAULTS}.backup.$(date +%Y%m%d-%H%M%S)"
STAGE="$(mktemp -t grub-defaults.XXXXXX)"
trap 'rm -f "$STAGE"' EXIT

cp "$GRUB_DEFAULTS" "$STAGE"

if grep -q '^GRUB_TIMEOUT_STYLE=' "$STAGE"; then
  sed -i 's/^GRUB_TIMEOUT_STYLE=.*/GRUB_TIMEOUT_STYLE=menu/' "$STAGE"
else
  printf '\nGRUB_TIMEOUT_STYLE=menu\n' >>"$STAGE"
fi

if grep -q '^GRUB_TIMEOUT=' "$STAGE"; then
  sed -i 's/^GRUB_TIMEOUT=.*/GRUB_TIMEOUT=-1/' "$STAGE"
else
  printf 'GRUB_TIMEOUT=-1\n' >>"$STAGE"
fi

if (( DRY_RUN )); then
  log "Would back up $GRUB_DEFAULTS to $BACKUP"
  log "Would write these GRUB timeout settings:"
  grep -E '^GRUB_TIMEOUT_STYLE=|^GRUB_TIMEOUT=' "$STAGE" | sed 's/^/  /'
  log "Would run: ${GRUB_UPDATE_CMD[*]}"
  exit 0
fi

cp "$GRUB_DEFAULTS" "$BACKUP"
cp "$STAGE" "$GRUB_DEFAULTS"

log "Updated $GRUB_DEFAULTS"
log "Backup saved to $BACKUP"
log "Regenerating GRUB configuration..."
"${GRUB_UPDATE_CMD[@]}"

log "Done. On next boot, the GRUB menu will wait until you choose an entry."
