#!/bin/bash
# Revision: 4
# First-boot provisioning for reTerminal DM — two-phase process.
#   Phase 1 (cloud-init): hostname, packages, reTerminal DM drivers → reboot
#   Phase 2 (systemd oneshot): kiosk, theme, LightDM, rotation → reboot
#
# Step implementations are downloaded from FILE_SERVER/steps/ and sourced.
# All fileserver assets live in cloud-init/fileserver/ in the repo.
#
# REQUIRES first-boot.conf — looked up in order:
#   1. <script-dir>/first-boot.conf
#   2. /tmp/first-boot.conf  (cloud-init runcmd downloads it)
#   3. /etc/cm4-provisioning/first-boot.conf
#   4. /var/lib/cm4-provisioning/first-boot.conf  (persisted for phase 2)
# Copy first-boot.conf.example → first-boot.conf and fill in all values.
# Disable steps: ENABLE_STEP_01=0 .. ENABLE_STEP_13=0

set -e
export DEBIAN_FRONTEND=noninteractive

# ── Phase tracking ──────────────────────────────────────────────────────
STATE_DIR="/var/lib/cm4-provisioning"
PHASE_FILE="$STATE_DIR/first-boot-phase"
PERSISTENT_SCRIPT="$STATE_DIR/first-boot.sh"
PERSISTENT_CONF="$STATE_DIR/first-boot.conf"
PHASE2_SERVICE="cm4-first-boot-phase2"
STEPS_DIR="/tmp/first-boot-steps"
LOGFILE="/var/log/first-boot.log"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]:-.}")" 2>/dev/null && pwd)"

# ── Load config (required) ──────────────────────────────────────────────
FIRST_BOOT_CONF=""
for _f in "$SCRIPT_DIR/first-boot.conf" /tmp/first-boot.conf \
          /etc/cm4-provisioning/first-boot.conf "$PERSISTENT_CONF"; do
  if [[ -f "$_f" ]]; then
    set -a && source "$_f" && set +a
    FIRST_BOOT_CONF="$_f"
    break
  fi
done
if [[ -z "$FIRST_BOOT_CONF" ]]; then
  echo "[$(date -Iseconds)] ERROR: first-boot.conf not found. Searched:" >&2
  echo "  $SCRIPT_DIR/first-boot.conf" >&2
  echo "  /tmp/first-boot.conf" >&2
  echo "  /etc/cm4-provisioning/first-boot.conf" >&2
  echo "  $PERSISTENT_CONF" >&2
  exit 1
fi

# Step enable flags (default: all enabled)
for _n in 01 02 03 04 05 06 07 08 09 10 11 12 13; do
  eval "ENABLE_STEP_${_n}=\"\${ENABLE_STEP_${_n}:-1}\""
done

# ── Derived ─────────────────────────────────────────────────────────────
PI_HOME="/home/$PI_USER"
AUTOSTART="$PI_HOME/.config/autostart"
[[ "$FILE_SERVER" =~ ^(https?://[^/]+) ]] && PORTAL_BASE="${BASH_REMATCH[1]}" || PORTAL_BASE=""
[[ -f "$PHASE_FILE" ]] && CURRENT_PHASE="$(cat "$PHASE_FILE")" || CURRENT_PHASE="1"

# ── Logging ─────────────────────────────────────────────────────────────
log() { echo "[$(date -Iseconds)] $*"; }
exec > >(tee -a "$LOGFILE") 2>&1
log "=== first-boot.sh phase $CURRENT_PHASE ==="
log "Config: $FIRST_BOOT_CONF"
log "FILE_SERVER=$FILE_SERVER  PI_USER=$PI_USER  HOSTNAME=$HOSTNAME"

# ── Portal status API ──────────────────────────────────────────────────
report_status() {
  [[ -z "$PORTAL_BASE" ]] && return 0
  curl -s --connect-timeout 5 --max-time 10 -X POST -H "Content-Type: application/json" \
    -d "{\"phase\":\"$1\",\"message\":\"$2\",\"step\":\"$3\",\"step_name\":\"$4\",\"hostname\":\"$HOSTNAME\",\"ip\":\"$5\"}" \
    "${PORTAL_BASE}/api/first-boot-status" || true
}
report_status "started" "Phase $CURRENT_PHASE started" "" "" ""

# ── Helpers (available to step scripts) ─────────────────────────────────
install_oneshot() {
  local name="$1"
  curl -fsSL "${FILE_SERVER}/${name}.sh"      -o "$PI_HOME/${name}.sh"      || { log "WARNING: ${name}.sh download failed"; return 1; }
  curl -fsSL "${FILE_SERVER}/${name}.desktop"  -o "$AUTOSTART/${name}.desktop" || { log "WARNING: ${name}.desktop download failed"; return 1; }
  chmod 755 "$PI_HOME/${name}.sh"
  chmod 644 "$AUTOSTART/${name}.desktop"
  chown "$PI_USER:$PI_USER" "$PI_HOME/${name}.sh" "$AUTOSTART/${name}.desktop"
  log "One-shot $name installed"
}

# ── Download, source, and run a step ────────────────────────────────────
run_step() {
  local n="$1" name="$2"
  local val; eval "val=\"\${ENABLE_STEP_${n}}\""
  val="${val//[^01]/}"
  if [[ "${val:0:1}" != "1" ]]; then
    log "--- Step $n: $name (disabled) ---"
    return 0
  fi
  log "--- Step $n: $name ---"
  local f="$STEPS_DIR/${n}-${name}.sh"
  curl -fsSL "${FILE_SERVER}/steps/${n}-${name}.sh" -o "$f" \
    || { log "ERROR: could not download step ${n}-${name}.sh"; return 1; }
  source "$f"
  "step_${n}_${name}"
  report_status "running" "Step $n: $name done" "$n" "$name" ""
}

# ── Phase transitions ──────────────────────────────────────────────────
phase1_reboot() {
  mkdir -p "$STATE_DIR"
  cp "$(readlink -f "${BASH_SOURCE[0]:-.}")" "$PERSISTENT_SCRIPT"
  chmod 755 "$PERSISTENT_SCRIPT"
  [[ -n "$FIRST_BOOT_CONF" && -f "$FIRST_BOOT_CONF" && "$FIRST_BOOT_CONF" != "$PERSISTENT_CONF" ]] \
    && cp "$FIRST_BOOT_CONF" "$PERSISTENT_CONF"
  echo "2" > "$PHASE_FILE"

  cat > "/etc/systemd/system/${PHASE2_SERVICE}.service" <<PHASE2SVC
[Unit]
Description=reTerminal DM first-boot phase 2
After=network-online.target
Wants=network-online.target

[Service]
Type=oneshot
ExecStart=$PERSISTENT_SCRIPT
StandardOutput=journal+console
TimeoutStartSec=600

[Install]
WantedBy=multi-user.target
PHASE2SVC
  systemctl daemon-reload
  systemctl enable "${PHASE2_SERVICE}.service"

  local ip; ip="$(hostname -I 2>/dev/null | awk '{print $1}')"
  report_status "phase1-done" "Phase 1 done, rebooting" "03" "reterminal_drivers" "$ip"
  log "=== Phase 1 done — rebooting to activate drivers ==="
  reboot
}

phase2_cleanup() {
  systemctl disable "${PHASE2_SERVICE}.service" 2>/dev/null || true
  rm -f "/etc/systemd/system/${PHASE2_SERVICE}.service"
  systemctl daemon-reload
  rm -f "$PHASE_FILE" "$PERSISTENT_SCRIPT" "$PERSISTENT_CONF"
  log "Phase 2 cleanup done"
}

# ── Main ────────────────────────────────────────────────────────────────
mkdir -p "$STEPS_DIR"

if [[ "$CURRENT_PHASE" == "1" ]]; then
  log "=== PHASE 1: hostname, packages, reTerminal drivers ==="
  run_step 01 hostname
  run_step 02 packages
  run_step 03 reterminal_drivers
  phase1_reboot

elif [[ "$CURRENT_PHASE" == "2" ]]; then
  log "=== PHASE 2: kiosk, theme, display config ==="
  run_step 04 kiosk_files
  run_step 05 splash_wallpaper
  run_step 06 lightdm
  run_step 07 maliit
  run_step 08 dark_theme
  run_step 09 reapply_splash
  run_step 10 cmdline
  run_step 11 oneshots
  run_step 12 log_permissions
  phase2_cleanup
  run_step 13 reboot

  # Only reached if step 13 (reboot) is disabled
  DEVICE_IP="$(hostname -I 2>/dev/null | awk '{print $1}')"
  report_status "done" "First-boot complete (reboot disabled)" "13" "reboot" "$DEVICE_IP"
  log "=== first-boot.sh finished (reboot disabled) ==="

else
  log "ERROR: Unknown phase '$CURRENT_PHASE'"; exit 1
fi
