#!/usr/bin/env bash
# veilor-os installer — TUI wrapper around anaconda kickstart install.
# Runs on tty1 in place of getty (live ISO boot path).
#
# Flow:
#   1. ASCII banner
#   2. Menu: Install / Live shell / Reboot / Power off
#   3. If Install: collect answers via whiptail (disk, hostname, LUKS pw,
#      admin pw, locale)
#   4. Generate /run/install/veilor-generated.ks from template + answers
#   5. Exec anaconda --kickstart=/run/install/veilor-generated.ks
#   6. On finish: reboot into installed system
#
# v0.5.0 — first cut. v0.5.1 swaps whiptail for gum (Go TUI, prettier).

set -uo pipefail
export TERM="${TERM:-linux}"
LOG=/var/log/veilor-installer.log
exec > >(tee -a "$LOG") 2>&1

banner() {
    clear
    cat << 'EOF'

   ▌ ▌▙▀▖▌ ▐▌▛▀▖▌ ▖▙▀▖▖▖
   ▙▖▌█  ▐▖▟▘▙▄▘▌ ▌▌  ▙▟
                        ▘
   veilor-os installer
   hardened. branded. yours.

EOF
    echo "──────────────────────────────────────────"
    echo
}

require_tty() {
    if ! [[ -t 0 && -t 1 ]]; then
        echo "[ERR] veilor-installer must run on a real tty" >&2
        exit 1
    fi
}

main_menu() {
    local choice
    choice=$(whiptail --title "veilor-os" \
        --menu "Welcome. What would you like to do?" 16 60 5 \
        "1" "Install veilor-os to disk" \
        "2" "Try live — desktop (KDE Plasma)" \
        "3" "Try live — shell" \
        "4" "Reboot" \
        "5" "Power off" \
        3>&1 1>&2 2>&3)
    echo "$choice"
}

collect_answers() {
    local disk hostname luks_pw admin_pw locale
    local disks_list

    # ── Disk ──
    disks_list=$(lsblk -dpno NAME,SIZE,MODEL | grep -E '^/dev/(sd|nvme|vd)' | awk '{print $1, $2"_"$3}')
    if [[ -z $disks_list ]]; then
        whiptail --title "veilor-os" --msgbox "No installable disks found." 8 50
        return 1
    fi
    disk=$(whiptail --title "Select install disk" \
        --menu "WARNING: selected disk will be ERASED." 18 70 8 \
        $disks_list 3>&1 1>&2 2>&3) || return 1

    # ── Hostname ──
    hostname=$(whiptail --title "Hostname" \
        --inputbox "Set hostname:" 10 60 "veilor" \
        3>&1 1>&2 2>&3) || return 1

    # ── LUKS passphrase ──
    luks_pw=$(whiptail --title "Disk encryption" \
        --passwordbox "LUKS passphrase (full-disk encryption):" 10 60 \
        3>&1 1>&2 2>&3) || return 1
    [[ ${#luks_pw} -lt 8 ]] && {
        whiptail --title "Weak passphrase" --msgbox "Min 8 chars." 8 40
        return 1
    }

    # ── Admin password ──
    admin_pw=$(whiptail --title "Admin password" \
        --passwordbox "Admin user password (login after install):" 10 60 \
        3>&1 1>&2 2>&3) || return 1
    [[ ${#admin_pw} -lt 8 ]] && {
        whiptail --title "Weak password" --msgbox "Min 8 chars." 8 40
        return 1
    }

    # ── Locale ──
    locale=$(whiptail --title "Locale" \
        --menu "Choose locale:" 14 50 4 \
        "en_GB.UTF-8" "English (UK)" \
        "en_US.UTF-8" "English (US)" \
        "de_DE.UTF-8" "Deutsch" \
        "fr_FR.UTF-8" "Francais" \
        3>&1 1>&2 2>&3) || return 1

    # ── Confirmation ──
    whiptail --title "Confirm install" --yesno \
"About to install veilor-os:

  Disk:       $disk (will be ERASED)
  Hostname:   $hostname
  Locale:     $locale
  LUKS:       set
  Admin pw:   set

Proceed?" 16 60 || return 1

    # Export to caller via globals
    SEL_DISK=$disk
    SEL_HOSTNAME=$hostname
    SEL_LUKS_PW=$luks_pw
    SEL_ADMIN_PW=$admin_pw
    SEL_LOCALE=$locale
    return 0
}

generate_ks() {
    # Build kickstart for actual disk install.
    # NOTE: passwords go in via --plaintext to avoid storing crypted hash
    # collisions; anaconda hashes per /etc/login.defs at install time.
    local out=/run/install/veilor-generated.ks
    mkdir -p /run/install
    cat > "$out" << EOF
# veilor-os installer-generated kickstart
# DO NOT commit this file — secrets inline.
url --mirrorlist="https://mirrors.fedoraproject.org/mirrorlist?repo=fedora-43&arch=x86_64"
repo --name=fedora --baseurl="https://download.fedoraproject.org/pub/fedora/linux/releases/43/Everything/x86_64/os/" --install
repo --name=updates --baseurl="https://download.fedoraproject.org/pub/fedora/linux/updates/43/Everything/x86_64/" --install

keyboard --xlayouts='us'
lang $SEL_LOCALE
timezone Europe/London --utc

firstboot --disable
eula --agreed
selinux --enforcing
services --enabled=sshd,fail2ban,usbguard,tuned,auditd,firewalld,chronyd,sddm

network --bootproto=dhcp --device=link --activate --hostname=$SEL_HOSTNAME
firewall --enabled --service=ssh

rootpw --lock
user --name=admin --groups=wheel --gecos="veilor admin" --password="$SEL_ADMIN_PW" --plaintext

# Full hardening cmdline (installed system, not live):
bootloader --location=mbr --append="lockdown=integrity slab_nomerge init_on_alloc=1 init_on_free=1 randomize_kstack_offset=on vsyscall=none"

# Disk: zero, LUKS2 (argon2id), btrfs subvolumes
zerombr
clearpart --all --initlabel --drives=$(basename "$SEL_DISK")
part /boot/efi --fstype=efi --size=600 --asprimary
part /boot --fstype=ext4 --size=1024 --asprimary
part pv.veilor --grow --encrypted --luks-version=luks2 --pbkdf=argon2id --passphrase="$SEL_LUKS_PW"
volgroup veilor pv.veilor
logvol / --vgname=veilor --name=root --fstype=btrfs --grow

%packages --excludedocs
@^kde-desktop-environment
@kde-apps
@core
@hardware-support
@standard
fail2ban
fail2ban-firewalld
usbguard
usbguard-tools
audit
policycoreutils-python-utils
tuned
chrony
firewalld
plymouth
git
vim-enhanced
tmux
htop
podman
NetworkManager
NetworkManager-wifi
fontconfig
fira-code-fonts
zram-generator
-abrt*
-snapd
-kde-connect
-mlocate
%end

# Reboot when done
reboot
EOF
    echo "[INFO] generated kickstart at $out"
    return 0
}

run_install() {
    whiptail --title "Installing" --infobox \
"Installing veilor-os to $SEL_DISK ...
This will take 10-30 minutes.
Logs: /var/log/veilor-installer.log + /tmp/anaconda.log" 10 60
    sleep 2
    # Hand off to anaconda. --kickstart runs unattended.
    if anaconda --kickstart=/run/install/veilor-generated.ks; then
        whiptail --title "Done" --msgbox \
"Install complete. System will reboot.
Remove the install media after shutdown." 10 50
        sleep 3
        systemctl reboot
    else
        whiptail --title "Install failed" --msgbox \
"Anaconda exited non-zero.
Logs at /tmp/anaconda.log + /var/log/veilor-installer.log.
Press OK to drop to shell." 12 60
        return 1
    fi
}

drop_to_shell() {
    clear
    cat << 'EOF'
═══════════════════════════════════════════════════
 veilor-os live shell
═══════════════════════════════════════════════════

You are in a live, in-memory environment.
Nothing persists across reboot.

Re-run the installer:    sudo veilor-installer
Reboot:                  sudo systemctl reboot
Power off:               sudo systemctl poweroff

EOF
    exec /bin/bash --login
}

# ── Entry ──
require_tty
banner

launch_desktop() {
    clear
    echo "Launching KDE Plasma..."
    sleep 1
    systemctl isolate graphical.target
    # systemd-isolate switches target; sddm spawns on tty1.
    # If user logs out, they come back here. Loop continues.
}

while true; do
    case "$(main_menu)" in
        1)
            if collect_answers && generate_ks; then
                run_install || continue
            fi
            ;;
        2) launch_desktop ;;
        3) drop_to_shell ;;
        4) systemctl reboot ;;
        5) systemctl poweroff ;;
        *) drop_to_shell ;;
    esac
done
