#!/usr/bin/env bash
#
# generalize-golden.sh — strip ALL instance state from a paas VM so it can be
# turned into a Proxmox template (qm template). Run as root on a THROWAWAY
# clone, never on a live server. The VM shuts down at the end.
#
#   sudo PREINSTALL_LARAVEL=1 ./infra/generalize-golden.sh
#
# PREINSTALL_LARAVEL=1 (recommended for the single "all features" template):
#   downloads the PHP-FPM/composer/MariaDB packages now and leaves their
#   services DISABLED, so a clone bootstrapped with WITH_LARAVEL=1 needs no
#   apt downloads, while a clone bootstrapped without the flag stays a plain
#   Node server (services off, nothing configured — identical to production).
#
# What survives (generic): OS + packages, Node/PM2, custom Caddy binary +
# systemd override, Varnish, chromium, Checkmk agent, GeoIP mmdb, the paas
# CLI + panel code with node_modules, all timers, sudoers, the deploy user
# (with the workstation key), the repo checkout at /home/younes/dotnews-paas.
# What is removed: apps, paas.db, panel .env/secrets, TLS certs + ACME
# account, deploy SSH keypair, logs/snapshots/builds, DB credentials + dumps,
# PHP pools, machine-id, SSH host keys, cloud-init state, shell histories.

set -euo pipefail
[[ "$(id -u)" -eq 0 ]] || { echo "run as root" >&2; exit 1; }
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
log() { printf '\n[generalize] %s\n' "$*"; }

read -rp "[generalize] This wipes every app, database, secret and key on $(hostname) and shuts it down. Type GENERALIZE to continue: " a
[[ "$a" == "GENERALIZE" ]] || { echo "aborted"; exit 1; }

# ------------------------------------------------ optional laravel preinstall ----
if [[ "${PREINSTALL_LARAVEL:-0}" == "1" ]]; then
    log "pre-installing PHP/composer/MariaDB packages (services stay disabled)"
    PHP_VERSIONS="${PHP_VERSIONS:-8.3 8.4}"
    if [[ ! -f /etc/apt/sources.list.d/sury-php.list ]]; then
        # shellcheck disable=SC1091
        . /etc/os-release
        curl -fsSL https://packages.sury.org/php/apt.gpg | gpg --dearmor --yes -o /usr/share/keyrings/deb.sury.org-php.gpg
        echo "deb [signed-by=/usr/share/keyrings/deb.sury.org-php.gpg] https://packages.sury.org/php/ $VERSION_CODENAME main" \
            >/etc/apt/sources.list.d/sury-php.list
    fi
    export DEBIAN_FRONTEND=noninteractive
    apt-get update -qq
    for V in $PHP_VERSIONS; do
        apt-get install -y -qq "php$V-fpm" "php$V-cli" "php$V-mysql" "php$V-mbstring" "php$V-xml" \
            "php$V-curl" "php$V-zip" "php$V-bcmath" "php$V-intl" "php$V-gd" "php$V-opcache" \
            "php$V-readline" "php$V-sqlite3" "php$V-redis" >/dev/null
        systemctl disable --now "php$V-fpm" >/dev/null 2>&1 || true
    done
    apt-get install -y -qq mariadb-server mariadb-client >/dev/null
    systemctl disable --now mariadb >/dev/null 2>&1 || true
    if ! command -v composer >/dev/null; then
        FIRST="${PHP_VERSIONS%% *}"
        EXPECTED="$(curl -fsSL https://composer.github.io/installer.sig)"
        curl -fsSL https://getcomposer.org/installer -o /tmp/composer-setup.php
        ACTUAL="$("/usr/bin/php$FIRST" -r "echo hash_file('sha384', '/tmp/composer-setup.php');")"
        [[ "$EXPECTED" == "$ACTUAL" ]] || { echo "composer installer checksum mismatch" >&2; exit 1; }
        "/usr/bin/php$FIRST" /tmp/composer-setup.php --quiet --install-dir=/usr/local/bin --filename=composer
        rm -f /tmp/composer-setup.php
    fi
fi

# --------------------------------------------------------- stop everything ----
log "stopping services"
sudo -u deploy -H bash -c 'cd /srv/paas && pm2 delete all >/dev/null 2>&1; pm2 save --force >/dev/null 2>&1; pm2 kill >/dev/null 2>&1' || true
systemctl stop caddy varnish 2>/dev/null || true
systemctl stop 'php*-fpm' mariadb 2>/dev/null || true
systemctl stop paas-traffic-rollup.timer paas-clicks-writeback.timer paas-geoip-refresh.timer \
    paas-google-crawlers-refresh.timer paas-laravel-scheduler.timer paas-db-backup.timer 2>/dev/null || true

# ------------------------------------------------------------ apps + paas ----
log "removing apps, registry, generated configs, database, panel secrets"
rm -rf /srv/apps/*
rm -rf /srv/paas/apps.d/* /srv/paas/caddy/app-*.caddy /srv/paas/caddy/panel.caddy
rm -f  /srv/paas/paas.db /srv/paas/paas.db-wal /srv/paas/paas.db-shm
rm -rf /srv/paas/builds/* /srv/paas/logs/* /srv/paas/snapshots/*
rm -f  /srv/paas/panel/.env /srv/paas/panel/run.sh
rm -rf /srv/paas/php/*/paas-*.conf /srv/paas/php/*/.staged /srv/paas/php/*/.bak
rm -f  /srv/paas/db-admin.cnf
rm -rf /srv/paas/backups
# varnish back to "no backends"
echo "backend b_paas_none none;" >/srv/paas/vcl/paas-backends.vcl
echo 'return (synth(421, "Misdirected Request"));' >/srv/paas/vcl/paas-routing.vcl
chown deploy:deploy /srv/paas/vcl/paas-*.vcl
# platform conf: keep SYSTEM_DOMAIN_BASE, drop runtime capability flags
if [[ -f /srv/paas/paas.conf ]]; then
    sed -i '/^RUNTIMES=/d;/^PHP_VERSIONS=/d;/^PHP_DEFAULT=/d' /srv/paas/paas.conf
fi
# laravel sudoers/timers are (re)written by bootstrap WITH_LARAVEL=1
rm -f /etc/sudoers.d/paas-laravel
rm -f /etc/systemd/system/paas-laravel-scheduler.* /etc/systemd/system/paas-db-backup.*
systemctl daemon-reload
# mariadb: drop anything a bootstrap may have created (app DBs + paas_admin)
if command -v mariadbd >/dev/null; then
    systemctl start mariadb 2>/dev/null || true
    mariadb -e "SELECT SCHEMA_NAME FROM information_schema.SCHEMATA WHERE SCHEMA_NAME NOT IN ('mysql','information_schema','performance_schema','sys')" -N -B 2>/dev/null \
        | while read -r d; do [[ -n "$d" ]] && mariadb -e "DROP DATABASE \`$d\`"; done
    mariadb -e "SELECT CONCAT(user,'@',host) FROM mysql.user WHERE user NOT IN ('root','mariadb.sys','mysql')" -N -B 2>/dev/null \
        | while read -r u; do [[ -n "$u" ]] && mariadb -e "DROP USER IF EXISTS ${u%@*}@'${u#*@}'"; done
    systemctl stop mariadb 2>/dev/null || true
    systemctl disable mariadb >/dev/null 2>&1 || true
    rm -f /etc/mysql/mariadb.conf.d/60-paas.cnf
fi
for V in /etc/php/*/; do
    [[ -d "$V" ]] || continue
    systemctl disable "php$(basename "$V")-fpm" >/dev/null 2>&1 || true
done

# ------------------------------------------------- first-boot wizard + banner ----
log "installing paas-init + login banner"
install -m 755 "$SCRIPT_DIR/bin/paas-init" /usr/local/bin/paas-init
cat >/etc/motd <<'EOF'

  ┌──────────────────────────────────────────────────────────────┐
  │  dotnews-paas golden clone — NOT SET UP YET                   │
  │                                                              │
  │  Run:   sudo paas-init                                        │
  │  It asks for the panel domain, admin password and flavour    │
  │  (Node.js like production, or Laravel with PHP-FPM/MariaDB)  │
  │  and then configures everything.                             │
  └──────────────────────────────────────────────────────────────┘

EOF

# ------------------------------------------------------- certs, keys, ids ----
log "removing TLS state, deploy key, machine identity"
rm -rf /var/lib/caddy/.local/share/caddy /var/lib/caddy/.config/caddy
rm -f  /home/deploy/.ssh/id_ed25519 /home/deploy/.ssh/id_ed25519.pub /home/deploy/.ssh/known_hosts
rm -f  /etc/ssh/ssh_host_*
truncate -s 0 /etc/machine-id
rm -f  /var/lib/dbus/machine-id; ln -s /etc/machine-id /var/lib/dbus/machine-id
command -v cloud-init >/dev/null && cloud-init clean --logs --seed 2>/dev/null || true

# ------------------------------------------------------------- housekeeping ----
log "housekeeping"
apt-get clean
journalctl --rotate >/dev/null 2>&1 || true; journalctl --vacuum-time=1s >/dev/null 2>&1 || true
rm -rf /tmp/* /var/tmp/* /root/.cache /home/*/.cache /home/deploy/.pm2/logs/* 2>/dev/null || true
rm -f /root/.bash_history /home/*/.bash_history /root/.mysql_history /home/*/.mysql_history
find /var/log -type f \( -name '*.gz' -o -name '*.[0-9]' \) -delete 2>/dev/null || true
find /var/log -type f -exec truncate -s 0 {} \; 2>/dev/null || true
# repo checkout: make sure it is at the commit we want in the template
if [[ -d "$SCRIPT_DIR/.git" ]]; then
    log "repo checkout at $(git -C "$SCRIPT_DIR" rev-parse --short HEAD) ($(git -C "$SCRIPT_DIR" log -1 --format=%s))"
fi

log "DONE — powering off. On Proxmox: qm template <this VMID>"
sync
poweroff
