#!/bin/sh
# firstboot-vps.sh — Phase 1: Install FreeBSD to disk from mfsBSD
#
# Runs on mfsBSD (FreeBSD in RAM) after SSH login.
# Partitions disk, installs base FreeBSD, injects the clawdie-iso
# firstboot payload, and reboots. On first HDD boot, the standard
# firstboot.sh pipeline handles everything else (wizard, packages,
# GPU, .env, deploy).
#
# Usage:
#   Interactive:  /usr/local/share/clawdie-iso/firstboot-vps.sh
#   Headless:     copy setup.txt.tpl → setup.txt, edit, then run
#
# Flow:
#   1. Detect target disk
#   2. Optionally read setup.txt for pre-baked values
#   3. Partition disk (GPT: EFI + swap + ZFS)
#   4. Create ZFS pool "clawdie" with standard datasets
#   5. Install FreeBSD base + kernel
#   6. Inject firstboot payload (same as installerconfig on USB)
#   7. Install bootloader + reboot
#
# After reboot, firstboot.sh runs the modular shell-*.sh pipeline:
#   zfs detect → wizard → gpu → pkg → ssh → env → system → tailscale → deploy

set -e

SHARE="${SHARE:-/usr/local/share/clawdie-iso}"
LOG="/var/log/clawdie-vps-install.log"

. "${SHARE}/build.cfg"
SETUP_IMPORT_TEST=1
. "${SHARE}/firstboot/setup-import.sh"

# ── Helpers ��──────────────────────────────────────────────────────────────

die() { echo "ERROR: $1" >&2; exit 1; }

log_vps() { echo "$(date '+%H:%M:%S') $1" | tee -a "$LOG"; }

gen_password() { openssl rand -base64 32 | tr -d '\n/+=' | head -c 24; }

detect_disk() {
  for d in /dev/nda0 /dev/nvd0 /dev/da0 /dev/vtbd0 /dev/ada0; do
    if [ -e "$d" ]; then
      echo "$d"
      return 0
    fi
  done
  die "Cannot detect target disk"
}

# ── Pre-baked config (headless) ───────────────────────────────────────────

if [ -f "${SHARE}/setup.txt" ]; then
  clawdie_setup_import_parse_file "${SHARE}/setup.txt" setup
  [ -f "${SHARE}/system.env" ] && clawdie_setup_import_parse_file "${SHARE}/system.env" system
  clawdie_setup_import_apply_defaults
  log_vps "[vps] Loaded setup.txt"
elif [ -f "${SHARE}/clawdie.conf" ]; then
  . "${SHARE}/clawdie.conf"
  log_vps "[vps] Loaded legacy clawdie.conf"
fi

# ── Detect disk ───────────────────────────────────────────────────────────

DISK=$(detect_disk)
log_vps "[vps] Target disk: ${DISK}"

# ── Interactive confirmation (if TTY available) ──────────────────────────

if [ -t 0 ] && command -v bsddialog >/dev/null 2>&1; then
  _dialog() { bsddialog --backtitle "Clawdie-VPS Setup" "$@" 2>&1; }

  _dialog --msgbox "\
Clawdie-VPS Installer

Target disk: ${DISK}
ALL DATA ON THIS DISK WILL BE ERASED.

After installation, the system will reboot and
run the standard Clawdie firstboot wizard." 12 60

  if ! _dialog --yesno "\
Confirm: ERASE ALL DATA on ${DISK} and install FreeBSD?" 8 60; then
    die "Cancelled."
  fi

  # Optional: pre-set TARGET for vps (skip wizard on reboot)
  if [ -n "${ASSISTANT_NAME:-}" ] && [ -n "${AGENT_DOMAIN:-}" ] && [ -n "${TZ:-}" ]; then
    _vps_target="vps"
    _dialog --msgbox "\
Pre-baked config detected:
  Agent:  ${ASSISTANT_NAME}
  Domain: ${AGENT_DOMAIN}
  TZ:     ${TZ}

Wizard will be skipped on first boot." 12 60
  else
    _vps_target="baremetal"
  fi
elif [ -t 0 ]; then
  echo "============================================"
  echo " Clawdie-VPS Installer"
  echo " Target disk: ${DISK}"
  echo " ALL DATA WILL BE ERASED."
  echo "============================================"
  printf "Continue? (yes/no): "
  read _confirm
  [ "$_confirm" = "yes" ] || die "Cancelled."
  _vps_target="baremetal"
else
  # No TTY — require setup.txt (legacy clawdie.conf still accepted temporarily)
  [ -n "${ASSISTANT_NAME:-}" ] || die "No TTY and no ASSISTANT_NAME in setup.txt"
  _vps_target="vps"
fi

# ── Step 1: Partition disk ────────────────────────────────────────────────

log_vps "[vps] [1/5] Partitioning ${DISK}..."

gpart destroy -F "${DISK}" 2>/dev/null || true
gpart create -s gpt "${DISK}"
gpart add -t efi -s 260M -l boot "${DISK}"
gpart add -t freebsd-swap -s 2G -l swap "${DISK}"
gpart add -t freebsd-zfs -l zroot "${DISK}"
newfs_msdos /dev/gpt/boot

# ── Step 2: Create ZFS pool ──────────────────────────────────────────────

log_vps "[vps] [2/5] Creating ZFS pool 'clawdie'..."

ZFS_PART="${DISK}p3"
[ -e "/dev/gpt/zroot" ] && ZFS_PART="/dev/gpt/zroot"

zpool create -f -m none -R /mnt clawdie "$ZFS_PART"
zfs create -o mountpoint=none              clawdie/ROOT
zfs create -o mountpoint=/                 clawdie/ROOT/default
zfs create -o mountpoint=/tmp  -o setuid=off clawdie/tmp
zfs create -o mountpoint=/usr  -o canmount=off clawdie/usr
zfs create -o mountpoint=/home             clawdie/home
zfs create -o mountpoint=/var  -o canmount=off clawdie/var
zfs create -o mountpoint=/var/cache -o setuid=off clawdie/var/cache
zfs create -o mountpoint=/var/log   -o setuid=off clawdie/var/log
zfs create -o mountpoint=/var/tmp   -o setuid=off clawdie/var/tmp
zfs create -o mountpoint=/var/db    clawdie/var/db
zfs set compression=lz4 clawdie
zfs set atime=off clawdie

# ── Step 3: Install FreeBSD base ─────────────────────────────────────────

log_vps "[vps] [3/5] Installing FreeBSD ${FREEBSD_VERSION} base..."

BASE_URL="https://download.freebsd.org/releases/${FREEBSD_ARCH}/${FREEBSD_VERSION}"
cd /tmp
fetch "${BASE_URL}/base.txz"   || die "Failed to fetch base.txz"
fetch "${BASE_URL}/kernel.txz" || die "Failed to fetch kernel.txz"
tar -xpf base.txz -C /mnt
tar -xpf kernel.txz -C /mnt

# fstab
cat > /mnt/etc/fstab <<EOF
/dev/gpt/boot   /boot/efi   msdosfs rw  0   0
/dev/gpt/swap   none        swap    sw  0   0
EOF

# loader.conf
cat > /mnt/boot/loader.conf <<EOF
zfs_load="YES"
mac_do_load="YES"
EOF

# mac_do framework starts with no credential grants. Specific rules are added
# only when a concrete operator workflow needs them.
cat > /mnt/etc/sysctl.conf <<EOF
security.mac.do.rules=
EOF

# Minimal rc.conf (firstboot.sh will configure the rest)
cat > /mnt/etc/rc.conf <<EOF
zfs_enable="YES"
sshd_enable="YES"
ifconfig_DEFAULT="DHCP"
clawdie_firstboot_enable="YES"
EOF

# Timezone
chroot /mnt tzsetup "${TZ:-UTC}"

# Create clawdie user
chroot /mnt pw useradd -n clawdie -u 1001 -m -G wheel -s /bin/sh
_root_pw=$(gen_password)
_user_pw=$(gen_password)
echo "root:$(openssl passwd -6 "$_root_pw")" | chroot /mnt chpass -H root
echo "clawdie:$(openssl passwd -6 "$_user_pw")" | chroot /mnt chpass -H clawdie

# sudo for wheel
mkdir -p /mnt/usr/local/etc/sudoers.d
cat > /mnt/usr/local/etc/sudoers.d/wheel <<EOF
%wheel ALL=(ALL) NOPASSWD: ALL
EOF
chmod 440 /mnt/usr/local/etc/sudoers.d/wheel

# ── Step 4: Inject firstboot payload ─────────────────────────────────────
# Same as installerconfig does for USB — copy firstboot scripts + packages + tarball

log_vps "[vps] [4/5] Injecting firstboot payload..."

HDD_SHARE="/mnt/usr/local/share/clawdie-iso"
HDD_RCD="/mnt/usr/local/etc/rc.d"

mkdir -p "$HDD_SHARE"
cp -r "${SHARE}/firstboot" "${HDD_SHARE}/"
cp    "${SHARE}/build.cfg" "${HDD_SHARE}/"

# Override TARGET in the HDD copy of build.cfg if pre-baked
if [ "$_vps_target" = "vps" ]; then
  sed -i '' "s/^TARGET=.*/TARGET=\"vps\"/" "${HDD_SHARE}/build.cfg"
  # Bake identity vars
  [ -n "${ASSISTANT_NAME:-}" ] && sed -i '' "s/^ASSISTANT_NAME=.*/ASSISTANT_NAME=\"${ASSISTANT_NAME}\"/" "${HDD_SHARE}/build.cfg"
  [ -n "${AGENT_DOMAIN:-}" ]   && sed -i '' "s/^AGENT_DOMAIN=.*/AGENT_DOMAIN=\"${AGENT_DOMAIN}\"/"     "${HDD_SHARE}/build.cfg"
  [ -n "${TZ:-}" ]             && sed -i '' "s|^TZ=.*|TZ=\"${TZ}\"|"                                    "${HDD_SHARE}/build.cfg"
  [ -n "${AGENT_GENDER:-}" ]   && sed -i '' "s/^AGENT_GENDER=.*/AGENT_GENDER=\"${AGENT_GENDER}\"/"     "${HDD_SHARE}/build.cfg"
  log_vps "[vps] Pre-baked config written to build.cfg (TARGET=vps)"
fi

# Copy tarball
if [ -f "${SHARE}/clawdie-ai.tar.gz" ]; then
  cp "${SHARE}/clawdie-ai.tar.gz" "${HDD_SHARE}/"
  log_vps "[vps] Clawdie-AI tarball copied"
else
  log_vps "[vps] WARNING: No clawdie-ai.tar.gz found — deploy step will fail"
fi

# Copy packages if bundled
if [ -d "${SHARE}/packages" ]; then
  cp -r "${SHARE}/packages" "${HDD_SHARE}/"
  log_vps "[vps] Package repo copied"
fi

# Make scripts executable
chmod +x "${HDD_SHARE}/firstboot/firstboot.sh"
for sh in "${HDD_SHARE}/firstboot/shell-"*.sh; do
  chmod +x "$sh"
done
chmod +x "${HDD_SHARE}/firstboot/zfs-pool-detect.sh"  2>/dev/null || true
chmod +x "${HDD_SHARE}/firstboot/zfs-pool-migrate.sh" 2>/dev/null || true
chmod +x "${HDD_SHARE}/firstboot/maintenance-mode.sh" 2>/dev/null || true

# Install rc.d service
mkdir -p "$HDD_RCD"
cp "${SHARE}/firstboot/rc.d/clawdie-firstboot" "${HDD_RCD}/clawdie-firstboot"
chmod +x "${HDD_RCD}/clawdie-firstboot"

# ── Step 5: Install bootloader + reboot ──────────────────────────────────

log_vps "[vps] [5/5] Installing EFI bootloader..."

[ -f /mnt/boot/loader.efi ] || die "loader.efi not found after base extraction"

mkdir -p /mnt/boot/efi
mount -t msdosfs /dev/gpt/boot /mnt/boot/efi
mkdir -p /mnt/boot/efi/EFI/BOOT
cp /mnt/boot/loader.efi /mnt/boot/efi/EFI/BOOT/BOOTX64.EFI
umount /mnt/boot/efi

zpool set bootfs=clawdie/ROOT/default clawdie

log_vps "[vps] Installation complete."
echo ""
echo "============================================"
echo " FreeBSD installed to ${DISK}"
echo " Pool: clawdie"
echo ""
echo " On first HDD boot, the Clawdie firstboot"
echo " wizard will run automatically."
echo ""
echo " Root password: ${_root_pw}"
echo " User password: ${_user_pw}"
echo ""
echo " SAVE THESE PASSWORDS NOW — they are not logged."
echo "============================================"
echo ""

# Export and reboot
log_vps "[vps] Exporting pool and rebooting in 10 seconds..."
sleep 10
umount /mnt/boot/efi 2>/dev/null || true
zpool export clawdie
reboot
