#!/usr/bin/env bash
# proxmox-lxc-gen.sh — TUI wizard for configuring and deploying Proxmox LXC containers.
#
# Walks through a step-by-step dialog interface covering every relevant LXC
# parameter, then writes three files to an output directory:
#
#   pct-create-<vmid>.sh   — runnable pct create command (execute on Proxmox host)
#   lxc-<vmid>.conf        — ready-to-drop /etc/pve/lxc/ config file
#   deploy-guide-<vmid>.txt — step-by-step deployment notes
#
# Optionally SSHs to the Proxmox host to run pct create directly.
#
# Requires: dialog   (pacman -S dialog / apt install dialog / dnf install dialog)

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SHELL_SCRIPTS_DIR="$SCRIPT_DIR/../Setup-shell-4-containers"

# ─── Helpers ──────────────────────────────────────────────────────────────────
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'
BLUE='\033[0;34m'; CYAN='\033[0;36m'; NC='\033[0m'
log()     { printf "${GREEN}[+]${NC} %s\n" "$*"; }
warn()    { printf "${YELLOW}[!]${NC} %s\n" "$*"; }
error()   { printf "${RED}[✗]${NC} %s\n" "$*" >&2; }
info()    { printf "${CYAN}[i]${NC} %s\n" "$*"; }
section() { printf "\n${BLUE}━━━ %s ━━━${NC}\n" "$*"; }

[[ $EUID -eq 0 ]] && { error "Run as a normal user (not root)."; exit 1; }

# ─── dialog dependency ────────────────────────────────────────────────────────
if ! command -v dialog &>/dev/null; then
    warn "dialog not found — attempting install..."
    if   command -v pacman  &>/dev/null; then sudo pacman  -S --noconfirm dialog
    elif command -v apt-get &>/dev/null; then sudo apt-get install -y dialog
    elif command -v dnf     &>/dev/null; then sudo dnf     install -y dialog
    else error "Install dialog manually, then re-run."; exit 1
    fi
fi

# ─── dialog theme ─────────────────────────────────────────────────────────────
TMP_D="$(mktemp -d)"
trap 'rm -rf "$TMP_D"' EXIT

BACKTITLE="Proxmox LXC Generator"
export DIALOGRC="$TMP_D/dialogrc"
cat > "$DIALOGRC" <<'DLRC'
use_shadow = ON
use_colors = ON
screen_color              = (BLACK,BLACK,ON)
title_color               = (CYAN,BLACK,ON)
border_color              = (CYAN,BLACK,ON)
button_active_color       = (BLACK,CYAN,ON)
button_inactive_color     = (WHITE,BLACK,OFF)
menubox_color             = (WHITE,BLACK,OFF)
menubox_border_color      = (CYAN,BLACK,ON)
item_color                = (WHITE,BLACK,OFF)
item_selected_color       = (BLACK,CYAN,ON)
tag_color                 = (CYAN,BLACK,ON)
tag_selected_color        = (BLACK,CYAN,ON)
check_color               = (WHITE,BLACK,OFF)
check_selected_color      = (BLACK,CYAN,ON)
inputbox_color            = (WHITE,BLACK,OFF)
inputbox_border_color     = (CYAN,BLACK,ON)
uarrow_color              = (CYAN,BLACK,ON)
darrow_color              = (CYAN,BLACK,ON)
DLRC

# Dialog wrapper: redirect stdout↔stderr so dialog output is captured.
D() { dialog --backtitle "$BACKTITLE" "$@" 3>&1 1>&2 2>&3; }
abort() { clear; echo "Aborted."; exit 0; }

# ─── Screen 1: Identity ───────────────────────────────────────────────────────
IDENTITY=$(D --title " Container Identity " \
    --form "\nSet the container ID, hostname, and optional metadata." \
    14 66 4 \
    "Container ID (VMID):"   1 1 "100" 1 26 8   9   \
    "Hostname:"              2 1 ""    2 26 32  253  \
    "Description (optional):" 3 1 ""  3 26 36  512  \
    "Tags (comma-separated):" 4 1 ""  4 26 36  512  \
) || abort

VMID=$(       awk 'NR==1' <<< "$IDENTITY")
CT_HOSTNAME=$(awk 'NR==2' <<< "$IDENTITY")
CT_DESC=$(    awk 'NR==3' <<< "$IDENTITY")
CT_TAGS=$(    awk 'NR==4' <<< "$IDENTITY")

[[ -z "$VMID" || ! "$VMID" =~ ^[0-9]{1,9}$ ]] && {
    error "VMID must be a positive integer (got: '${VMID}')."; exit 1; }
[[ -z "$CT_HOSTNAME" ]] && { error "Hostname is required."; exit 1; }

# ─── Screen 2: OS / Template ──────────────────────────────────────────────────
TMPL_DISTRO=$(D --title " OS / Template " \
    --menu "\nSelect the base distribution.\nThe matching CT template will be located via pveam on Proxmox." \
    20 66 9 \
    "debian"   "Debian 12 Bookworm   — stable, recommended default" \
    "ubuntu"   "Ubuntu 24.04 LTS     — popular, snap support" \
    "alpine"   "Alpine Linux         — minimal, musl, ~10 MB" \
    "arch"     "Arch Linux           — rolling release" \
    "fedora"   "Fedora               — recent packages, rpm" \
    "rocky"    "Rocky Linux 9        — RHEL-compatible enterprise" \
    "centos"   "CentOS Stream 9      — RHEL upstream" \
    "void"     "Void Linux           — runit init, musl/glibc" \
    "custom"   "Custom template      — enter filename manually" \
) || abort

case "$TMPL_DISTRO" in
    debian)  CT_OSTYPE="debian";    TMPL_PATTERN="debian-12"          ;;
    ubuntu)  CT_OSTYPE="ubuntu";    TMPL_PATTERN="ubuntu-24.04"       ;;
    alpine)  CT_OSTYPE="alpine";    TMPL_PATTERN="alpine-3"           ;;
    arch)    CT_OSTYPE="archlinux"; TMPL_PATTERN="archlinux-base"     ;;
    fedora)  CT_OSTYPE="fedora";    TMPL_PATTERN="fedora-"            ;;
    rocky)   CT_OSTYPE="centos";    TMPL_PATTERN="rockylinux-9"       ;;
    centos)  CT_OSTYPE="centos";    TMPL_PATTERN="centos-9-stream"    ;;
    void)    CT_OSTYPE="unmanaged"; TMPL_PATTERN="voidlinux-"         ;;
    custom)  CT_OSTYPE="unmanaged"; TMPL_PATTERN=""                   ;;
esac

if [[ "$TMPL_DISTRO" == "custom" ]]; then
    CT_TEMPLATE=$(D --title " Custom Template " \
        --inputbox \
"Enter the exact template filename as shown by pveam available.
Example: debian-12-standard_12.7-1_amd64.tar.zst" \
        10 72 "") || abort
    [[ -z "$CT_TEMPLATE" ]] && { error "Template filename is required."; exit 1; }
else
    CT_TEMPLATE="$TMPL_PATTERN"   # resolved to the full name on Proxmox at deploy time
fi

# ─── Screen 3: Resources ──────────────────────────────────────────────────────
RESOURCES=$(D --title " Resources " \
    --form "\nAllocate compute and storage resources for the container." \
    15 66 5 \
    "Memory (MB):"      1 1 "512"       1 22 10 10 \
    "Swap (MB):"        2 1 "512"       2 22 10 10 \
    "CPU cores:"        3 1 "1"         3 22 5  4  \
    "Disk size (GB):"   4 1 "8"         4 22 10 10 \
    "Rootfs storage:"   5 1 "local-lvm" 5 22 24 64 \
) || abort

CT_MEMORY=$(awk 'NR==1' <<< "$RESOURCES")
CT_SWAP=$(  awk 'NR==2' <<< "$RESOURCES")
CT_CORES=$( awk 'NR==3' <<< "$RESOURCES")
CT_DISK=$(  awk 'NR==4' <<< "$RESOURCES")
CT_STORAGE=$(awk 'NR==5' <<< "$RESOURCES")

for _f in CT_MEMORY CT_SWAP CT_CORES CT_DISK; do
    [[ "${!_f}" =~ ^[0-9]+$ ]] || { error "$_f must be a number (got: '${!_f}')."; exit 1; }
done

# ─── Screen 4: Network ────────────────────────────────────────────────────────
CT_NET_MODE=$(D --title " Network — IP Assignment " \
    --radiolist "\nChoose how the container obtains its IP address:" \
    10 56 2 \
    "dhcp"   "DHCP  (automatic — recommended for most setups)" ON  \
    "static" "Static IP address (you specify CIDR + gateway)"  OFF \
) || abort

CT_IP="" CT_GW="" CT_DNS="8.8.8.8" CT_SEARCHDOMAIN=""

if [[ "$CT_NET_MODE" == "static" ]]; then
    STATIC=$(D --title " Static Network " \
        --form "\nEnter static network settings for this container." \
        14 68 4 \
        "IP address (CIDR):"  1 1 "192.168.1.100/24" 1 24 22 18  \
        "Gateway:"            2 1 "192.168.1.1"      2 24 16 15  \
        "DNS server:"         3 1 "8.8.8.8"          3 24 16 15  \
        "Search domain:"      4 1 ""                 4 24 36 255 \
    ) || abort
    CT_IP=$(         awk 'NR==1' <<< "$STATIC")
    CT_GW=$(         awk 'NR==2' <<< "$STATIC")
    CT_DNS=$(        awk 'NR==3' <<< "$STATIC")
    CT_SEARCHDOMAIN=$(awk 'NR==4' <<< "$STATIC")
fi

NET_ADV=$(D --title " Network — Interface " \
    --form "\nConfigure the virtual NIC attached to this container." \
    12 60 3 \
    "Bridge:"          1 1 "vmbr0" 1 18 16 16 \
    "VLAN tag (blank=none):" 2 1 ""    2 18 6  4  \
    "Enable firewall [0/1]:" 3 1 "1"   3 18 2  1  \
) || abort
CT_BRIDGE=$(  awk 'NR==1' <<< "$NET_ADV")
CT_VLAN=$(    awk 'NR==2' <<< "$NET_ADV")
CT_FIREWALL=$(awk 'NR==3' <<< "$NET_ADV")
[[ "$CT_FIREWALL" != "1" ]] && CT_FIREWALL=0

# ─── Screen 5: Security ───────────────────────────────────────────────────────
UNPRIV=$(D --title " Privilege Level " \
    --radiolist \
"\nUnprivileged containers map UIDs to avoid host root exposure (recommended).
Privileged containers share the host UID namespace — needed for some services
(e.g. FreeIPA, NFS server) but should only be used when necessary." \
    13 72 2 \
    "unprivileged" "Unprivileged  — UID remapping, recommended" ON  \
    "privileged"   "Privileged    — full host UIDs, reduced isolation" OFF \
) || abort
[[ "$UNPRIV" == "unprivileged" ]] && CT_UNPRIVILEGED=1 || CT_UNPRIVILEGED=0

FEATURES_RAW=$(D --title " LXC Features " \
    --separate-output \
    --checklist \
"\nSelect kernel features to enable for this container.
Use Space to toggle, Enter to confirm." \
    18 72 7 \
    "nesting"   "nesting=1  — run Docker or nested LXC inside this container" OFF \
    "fuse"      "fuse=1     — allow FUSE mounts (sshfs, rclone, etc.)"        OFF \
    "keyctl"    "keyctl=1   — Linux keyring API (required by some services)"   OFF \
    "mounts"    "mounts=fuse — permit FUSE bind-mounts"                        OFF \
    "apparmor"  "Unconfined AppArmor profile (privileged workaround)"          OFF \
    "cgroup"    "cgroup:rw mounts (needed by systemd inside container)"        OFF \
    "seccomp"   "seccomp=0  — disable seccomp filtering (last resort only)"   OFF \
) || true   # OK if nothing selected

CT_FEATURES="" CT_APPARMOR=0 CT_CGROUP=0 CT_SECCOMP=""
while IFS= read -r _feat; do
    [[ -z "$_feat" ]] && continue
    case "$_feat" in
        nesting)  CT_FEATURES+="nesting=1,"   ;;
        fuse)     CT_FEATURES+="fuse=1,"      ;;
        keyctl)   CT_FEATURES+="keyctl=1,"    ;;
        mounts)   CT_FEATURES+="mounts=fuse," ;;
        apparmor) CT_APPARMOR=1               ;;
        cgroup)   CT_CGROUP=1                 ;;
        seccomp)  CT_SECCOMP="lxc.seccomp.profile:"  ;;
    esac
done <<< "$FEATURES_RAW"
CT_FEATURES="${CT_FEATURES%,}"

# ─── Screen 6: Options ────────────────────────────────────────────────────────
# Root password via passwordbox (hidden input), remaining options via form.
CT_ROOT_PW=$(D --title " Root Password " \
    --insecure \
    --passwordbox \
"Enter the root password for this container.
Leave blank to disable password auth (SSH key recommended)." \
    10 62 "") || abort

OPTIONS=$(D --title " Container Options " \
    --form "\nFinal container settings." \
    13 68 4 \
    "SSH pubkey file (blank=skip):"   1 1 "" 1 34 30 256 \
    "Start on boot [0/1]:"           2 1 "0" 2 34 2  1   \
    "Start after creation [y/n]:"    3 1 "n" 3 34 2  1   \
    "Console/TTY count:"             4 1 "2" 4 34 3  3   \
) || abort

CT_SSHKEY=$(   awk 'NR==1' <<< "$OPTIONS")
CT_ONBOOT=$(   awk 'NR==2' <<< "$OPTIONS")
CT_AUTOSTART=$(awk 'NR==3' <<< "$OPTIONS")
CT_TTY=$(      awk 'NR==4' <<< "$OPTIONS")
[[ "$CT_ONBOOT" != "1" ]] && CT_ONBOOT=0
[[ "${CT_AUTOSTART,,}" == "y"* ]] && CT_AUTOSTART=true || CT_AUTOSTART=false
CT_SSHKEY="${CT_SSHKEY/#\~/$HOME}"
if [[ -n "$CT_SSHKEY" && ! -f "$CT_SSHKEY" ]]; then
    warn "SSH key file not found: $CT_SSHKEY (will be ignored)"
    CT_SSHKEY=""
fi

# ─── Screen 7: Proxmox target ─────────────────────────────────────────────────
PVE_FORM=$(D --title " Proxmox Host " \
    --form \
"\nLeave 'Proxmox host' blank to generate output files only (no deployment).
SSH target format: root@192.168.1.10  or  root@pve.example.com" \
    15 72 4 \
    "Proxmox host (blank=local only):"  1 1 ""                       1 36 30 255 \
    "Template storage (pveam target):"  2 1 "local"                  2 36 20 64  \
    "Output directory:"                 3 1 "$HOME/proxmox-lxc"      3 36 30 255 \
    "Proxmox node name:"                4 1 "pve"                    4 36 20 64  \
) || abort

PVE_HOST=$(    awk 'NR==1' <<< "$PVE_FORM")
TMPL_STORAGE=$(awk 'NR==2' <<< "$PVE_FORM")
OUTPUT_DIR=$(  awk 'NR==3' <<< "$PVE_FORM")
PVE_NODE=$(    awk 'NR==4' <<< "$PVE_FORM")
OUTPUT_DIR="${OUTPUT_DIR/#\~/$HOME}"
[[ -z "$TMPL_STORAGE" ]] && TMPL_STORAGE="local"
[[ -z "$PVE_NODE"     ]] && PVE_NODE="pve"

# ─── Assemble net0 string ─────────────────────────────────────────────────────
_NET="name=eth0,bridge=${CT_BRIDGE}"
[[ -n "$CT_VLAN" && "$CT_VLAN" =~ ^[0-9]+$ ]] && _NET+=",tag=${CT_VLAN}"
if [[ "$CT_NET_MODE" == "dhcp" ]]; then
    _NET+=",ip=dhcp,ip6=auto"
else
    _NET+=",ip=${CT_IP}"
    [[ -n "$CT_GW" ]] && _NET+=",gw=${CT_GW}"
fi
[[ "$CT_FIREWALL" == "1" ]] && _NET+=",firewall=1"

# ─── Confirm summary ──────────────────────────────────────────────────────────
SUMMARY="  VMID         : $VMID
  Hostname      : $CT_HOSTNAME
  Description   : ${CT_DESC:-(none)}
  Tags          : ${CT_TAGS:-(none)}

  OS / template : $TMPL_DISTRO  ($CT_TEMPLATE)
  OS type       : $CT_OSTYPE

  Memory        : ${CT_MEMORY} MB
  Swap          : ${CT_SWAP} MB
  CPU cores     : $CT_CORES
  Disk          : ${CT_DISK} GB on $CT_STORAGE

  Network       : $_NET
  DNS           : ${CT_DNS}${CT_SEARCHDOMAIN:+ / $CT_SEARCHDOMAIN}

  Unprivileged  : $([[ "$CT_UNPRIVILEGED" == 1 ]] && echo yes || echo 'NO — privileged')
  Features      : ${CT_FEATURES:-(none)}
  AppArmor      : $([[ "$CT_APPARMOR" == 1 ]] && echo unconfined || echo default)
  cgroup rw     : $([[ "$CT_CGROUP"   == 1 ]] && echo yes || echo no)

  Root PW set   : $([[ -n "$CT_ROOT_PW" ]] && echo yes || echo no)
  SSH pubkey    : ${CT_SSHKEY:-(none)}
  Start on boot : $CT_ONBOOT
  Auto-start    : $CT_AUTOSTART
  TTY count     : $CT_TTY

  Output dir    : $OUTPUT_DIR
  Proxmox host  : ${PVE_HOST:-(local — files only)}"

D --title " Configuration Summary " \
    --ok-label "Generate" \
    --cancel-label "Abort" \
    --scrolltext \
    --msgbox "$SUMMARY" 38 68 || abort

clear

# ─── Generate output files ────────────────────────────────────────────────────
mkdir -p "$OUTPUT_DIR"
section "Generating output files → $OUTPUT_DIR"

# ── pct-create script ─────────────────────────────────────────────────────────
PCT_SCRIPT="$OUTPUT_DIR/pct-create-${VMID}.sh"
{
    printf '#!/usr/bin/env bash\n'
    printf '# pct-create-%s.sh — generated by proxmox-lxc-gen.sh  %s\n' "$VMID" "$(date -Iseconds)"
    printf '# Run on the Proxmox host as root.\n\n'
    printf 'set -euo pipefail\n\n'

    if [[ "$TMPL_DISTRO" != "custom" ]]; then
        printf '# ── Resolve template ──────────────────────────────────────────────────────────\n'
        printf 'TEMPLATE=$(pveam available --section system 2>/dev/null \\\n'
        printf '    | awk '"'"'/%s/ {print $2; exit}'"'"')\n' "$CT_TEMPLATE"
        printf '[[ -z "$TEMPLATE" ]] && TEMPLATE=$(pveam available --section turnkeylinux 2>/dev/null \\\n'
        printf '    | awk '"'"'/%s/ {print $2; exit}'"'"') || true\n' "$CT_TEMPLATE"
        printf 'if [[ -z "$TEMPLATE" ]]; then\n'
        printf '    echo "ERROR: no template matching '"'"'%s'"'"' found." >&2\n' "$CT_TEMPLATE"
        printf '    echo "Run: pveam update && pveam available --section system" >&2\n'
        printf '    exit 1\n'
        printf 'fi\n'
        printf 'echo "Resolved template: $TEMPLATE"\n\n'
        printf '# Download template if not already cached\n'
        printf 'pveam download %s "$TEMPLATE" 2>/dev/null \\\n' "$TMPL_STORAGE"
        printf '    && echo "Template downloaded." \\\n'
        printf '    || echo "Template already present (or download failed — continuing)"\n\n'
    else
        printf 'TEMPLATE="%s"\n\n' "$CT_TEMPLATE"
    fi

    printf '# ── Create the container ──────────────────────────────────────────────────────\n'
    printf 'pct create %s \\\n' "$VMID"
    printf '    %s:vztmpl/"$TEMPLATE" \\\n' "$TMPL_STORAGE"
    printf '    --hostname "%s" \\\n' "$CT_HOSTNAME"
    printf '    --ostype  "%s" \\\n' "$CT_OSTYPE"
    printf '    --memory  %s \\\n'   "$CT_MEMORY"
    printf '    --swap    %s \\\n'   "$CT_SWAP"
    printf '    --cores   %s \\\n'   "$CT_CORES"
    printf '    --rootfs  "%s:%s" \\\n' "$CT_STORAGE" "$CT_DISK"
    printf '    --net0    "%s" \\\n' "$_NET"
    [[ -n "$CT_DNS" ]]           && printf '    --nameserver   "%s" \\\n' "$CT_DNS"
    [[ -n "$CT_SEARCHDOMAIN" ]]  && printf '    --searchdomain "%s" \\\n' "$CT_SEARCHDOMAIN"
    printf '    --unprivileged %s \\\n' "$CT_UNPRIVILEGED"
    [[ -n "$CT_FEATURES" ]]      && printf '    --features "%s" \\\n' "$CT_FEATURES"
    printf '    --onboot  %s \\\n'   "$CT_ONBOOT"
    printf '    --tty     %s \\\n'   "$CT_TTY"
    [[ -n "$CT_ROOT_PW" ]]       && printf '    --password "%s" \\\n' "$CT_ROOT_PW"
    [[ -n "$CT_SSHKEY" ]]        && printf '    --ssh-public-keys "%s" \\\n' "$CT_SSHKEY"
    [[ -n "$CT_DESC" ]]          && printf '    --description "%s" \\\n' "${CT_DESC//\"/\\\"}"
    [[ -n "$CT_TAGS" ]]          && printf '    --tags "%s" \\\n' "$CT_TAGS"
    printf '    --start 0\n\n'

    if [[ "$CT_APPARMOR" == 1 || "$CT_CGROUP" == 1 || -n "$CT_SECCOMP" ]]; then
        printf '# ── Apply extra lxc.* options ────────────────────────────────────────────────\n'
        printf 'CONF="/etc/pve/lxc/%s.conf"\n' "$VMID"
        [[ "$CT_APPARMOR" == 1 ]] && printf 'printf '"'"'lxc.apparmor.profile: unconfined\nlxc.cap.drop:\n'"'"' >> "$CONF"\n'
        [[ "$CT_CGROUP"   == 1 ]] && printf 'printf '"'"'lxc.mount.auto: proc:rw sys:rw cgroup:rw\nlxc.cgroup2.devices.allow: a\n'"'"' >> "$CONF"\n'
        [[ -n "$CT_SECCOMP"   ]] && printf 'printf '"'"'lxc.seccomp.profile:\n'"'"' >> "$CONF"\n'
        printf '\n'
    fi

    if [[ "$CT_AUTOSTART" == true ]]; then
        printf '# ── Start the container ──────────────────────────────────────────────────────\n'
        printf 'pct start %s\n' "$VMID"
        printf 'echo "Container %s is running."\n' "$VMID"
        printf 'echo "Access: pct enter %s   or   ssh root@<container-ip>"\n\n' "$VMID"
    fi

    printf 'echo "Done. Container %s created."\n' "$VMID"
} > "$PCT_SCRIPT"
chmod 755 "$PCT_SCRIPT"
log "pct create script: $(basename "$PCT_SCRIPT")"

# ── LXC conf file ─────────────────────────────────────────────────────────────
LXC_CONF="$OUTPUT_DIR/lxc-${VMID}.conf"
{
    printf '# Generated by proxmox-lxc-gen.sh — %s\n' "$(date -Iseconds)"
    printf '# Install: cp %s /etc/pve/lxc/%s.conf\n\n' "$(basename "$LXC_CONF")" "$VMID"
    printf 'arch: amd64\n'
    printf 'cores: %s\n'   "$CT_CORES"
    printf 'hostname: %s\n' "$CT_HOSTNAME"
    printf 'memory: %s\n'  "$CT_MEMORY"
    printf 'swap: %s\n'    "$CT_SWAP"
    printf 'net0: %s\n'    "$_NET"
    printf 'ostype: %s\n'  "$CT_OSTYPE"
    printf 'rootfs: %s:vm-%s-disk-0,size=%sG\n' "$CT_STORAGE" "$VMID" "$CT_DISK"
    printf 'unprivileged: %s\n' "$CT_UNPRIVILEGED"
    printf 'onboot: %s\n'  "$CT_ONBOOT"
    printf 'tty: %s\n'     "$CT_TTY"
    [[ -n "$CT_FEATURES"     ]] && printf 'features: %s\n'      "$CT_FEATURES"
    [[ -n "$CT_DNS"          ]] && printf 'nameserver: %s\n'    "$CT_DNS"
    [[ -n "$CT_SEARCHDOMAIN" ]] && printf 'searchdomain: %s\n' "$CT_SEARCHDOMAIN"
    [[ -n "$CT_TAGS"         ]] && printf 'tags: %s\n'         "$CT_TAGS"
    [[ -n "$CT_DESC"         ]] && printf 'description: %s\n'  "$CT_DESC"
    if [[ "$CT_APPARMOR" == 1 ]]; then
        printf '\n# AppArmor override (applied post-create)\n'
        printf 'lxc.apparmor.profile: unconfined\n'
        printf 'lxc.cap.drop:\n'
    fi
    if [[ "$CT_CGROUP" == 1 ]]; then
        printf '\n# cgroup access override (required by systemd in containers)\n'
        printf 'lxc.mount.auto: proc:rw sys:rw cgroup:rw\n'
        printf 'lxc.cgroup2.devices.allow: a\n'
    fi
    [[ -n "$CT_SECCOMP" ]] && printf '\nlxc.seccomp.profile:\n'
} > "$LXC_CONF"
log "LXC conf:          $(basename "$LXC_CONF")"

# ── Deploy guide ──────────────────────────────────────────────────────────────
GUIDE="$OUTPUT_DIR/deploy-guide-${VMID}.txt"
{
printf 'Proxmox LXC deploy guide  —  generated %s
══════════════════════════════════════════════════════════════════════════

  Container : %s  (VMID %s)
  OS        : %s (%s)
  Resources : %s core(s), %s MB RAM, %s GB disk on %s
  Network   : %s
  Privilege : %s

━━━ Step 1 — Upload files to Proxmox ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  scp %s/pct-create-%s.sh root@<proxmox>:/tmp/
' \
    "$(date -Iseconds)" \
    "$CT_HOSTNAME" "$VMID" \
    "$TMPL_DISTRO" "$CT_OSTYPE" \
    "$CT_CORES" "$CT_MEMORY" "$CT_DISK" "$CT_STORAGE" \
    "$_NET" \
    "$([[ "$CT_UNPRIVILEGED" == 1 ]] && echo unprivileged || echo 'PRIVILEGED')" \
    "$OUTPUT_DIR" "$VMID"

printf '━━━ Step 2 — Update template catalogue and create container ━━━━━━━━━━━━━

  ssh root@<proxmox>
  pveam update
  bash /tmp/pct-create-%s.sh

  The script resolves the latest matching template for "%s",
  downloads it if not cached, and calls pct create with all
  parameters from this wizard.

━━━ Step 3 — Verify ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  pct list
  pct status %s
  pct config %s

━━━ Step 4 — Access the container ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  # Console (always available):
  pct start %s
  pct enter %s

' \
    "$VMID" "$CT_TEMPLATE" \
    "$VMID" "$VMID" \
    "$VMID" "$VMID"

if [[ "$CT_NET_MODE" == "static" ]]; then
    printf '  # SSH (static IP configured):\n  ssh root@%s\n\n' "${CT_IP%%/*}"
else
    printf '  # SSH (find DHCP IP via):\n'
    printf '  pct exec %s -- ip -4 addr show eth0\n\n' "$VMID"
fi

printf '━━━ Step 5 — Post-install shell setup (optional) ━━━━━━━━━━━━━━━━━━━━━━

  # Run inside the container to set up the shell environment:
'
case "$TMPL_DISTRO" in
    debian|ubuntu)
        printf '  pct exec %s -- bash /path/to/Setup-shell-4-containers/debian.sh\n' "$VMID" ;;
    arch)
        printf '  pct exec %s -- bash /path/to/Setup-shell-4-containers/arch.sh\n'   "$VMID" ;;
    alpine)
        printf '  pct exec %s -- ash  /path/to/Setup-shell-4-containers/alpine.sh\n' "$VMID" ;;
    fedora|rocky|centos)
        printf '  pct exec %s -- bash /path/to/Setup-shell-4-containers/fedora.sh\n' "$VMID" ;;
    void)
        printf '  pct exec %s -- bash /path/to/Setup-shell-4-containers/void.sh\n'   "$VMID" ;;
    *)
        printf '  # See setup/Setup-shell-4-containers/ for distro-specific scripts\n' ;;
esac

printf '\n━━━ Notes ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n'

[[ "$CT_UNPRIVILEGED" == 0 ]] && printf \
'  PRIVILEGED container — reduced isolation. If services fail with
  permission errors, verify these are in /etc/pve/lxc/%s.conf:
    lxc.apparmor.profile: unconfined
    lxc.cap.drop:\n\n' "$VMID"

[[ "$CT_APPARMOR" == 1 ]] && printf \
'  AppArmor profile: unconfined — container has reduced AppArmor isolation.
  Only use for trusted workloads (FreeIPA, Docker-in-LXC, etc.).\n\n'

[[ "$CT_CGROUP" == 1 ]] && printf \
'  cgroup:rw enabled — container has full cgroup access.
  Required by systemd services that manage their own cgroups.\n\n'

[[ -n "$CT_FEATURES" ]] && printf '  LXC features: %s\n\n' "$CT_FEATURES"

printf \
'  Useful pct commands:
    pct set %s --memory 2048   update a setting live
    pct snapshot %s before-update  take a snapshot
    pct rollback %s before-update  revert to snapshot
    pct destroy %s              delete the container (irreversible)
    pvesh get /nodes/%s/lxc/%s/status/current

  Generated config: %s
  Proxmox path:     /etc/pve/lxc/%s.conf
' \
    "$VMID" "$VMID" "$VMID" "$VMID" \
    "$PVE_NODE" "$VMID" \
    "$(basename "$LXC_CONF")" "$VMID"
} > "$GUIDE"
log "Deploy guide:      $(basename "$GUIDE")"

# ─── Optional: SSH deploy ─────────────────────────────────────────────────────
if [[ -n "$PVE_HOST" ]]; then
    section "Deploying to $PVE_HOST"

    info "Uploading pct-create-${VMID}.sh..."
    scp "$PCT_SCRIPT" "${PVE_HOST}:/tmp/pct-create-${VMID}.sh"

    if [[ -n "$CT_SSHKEY" ]]; then
        info "Uploading SSH public key..."
        scp "$CT_SSHKEY" "${PVE_HOST}:/tmp/lxc-sshkey-${VMID}.pub"
        ssh "$PVE_HOST" \
            "sed -i 's|${CT_SSHKEY}|/tmp/lxc-sshkey-${VMID}.pub|' /tmp/pct-create-${VMID}.sh"
    fi

    info "Running pct create on $PVE_HOST (this may take a moment)..."
    if ssh "$PVE_HOST" "bash /tmp/pct-create-${VMID}.sh"; then
        log "Container $VMID created on $PVE_HOST"
    else
        warn "pct create reported an error — check the output above"
    fi
    ssh "$PVE_HOST" "rm -f /tmp/pct-create-${VMID}.sh /tmp/lxc-sshkey-${VMID}.pub" 2>/dev/null || true
fi

# ─── Final summary ────────────────────────────────────────────────────────────
section "Done"
printf '\n'
info "Output: $OUTPUT_DIR/"
printf '    %-36s  pct create command\n'       "pct-create-${VMID}.sh"
printf '    %-36s  LXC config (→ /etc/pve/lxc/)\n' "lxc-${VMID}.conf"
printf '    %-36s  step-by-step notes\n'       "deploy-guide-${VMID}.txt"
printf '\n'
if [[ -z "$PVE_HOST" ]]; then
    info "To deploy, copy to your Proxmox host and run:"
    printf '    scp %s/pct-create-%s.sh root@<proxmox>:/tmp/\n' "$OUTPUT_DIR" "$VMID"
    printf '    ssh root@<proxmox> "bash /tmp/pct-create-%s.sh"\n' "$VMID"
fi
