#!/usr/bin/env bash
# =====================================================================
# Refresh the LogShip golden template from the latest production backup
# ---------------------------------------------------------------------
# Runs ON prox2 (needs qm/qmrestore/pvesh). Phases 1+2 of RECLONE-RUNBOOK:
#   restore PBS backup of VM 105 as a NEW VM -> quarantined first boot
#   (NIC link_down) -> copy cleanup scripts in via guest agent -> defuse
#   + neutralize .env while still offline -> bring the NIC up.
# Production VM 105 is never touched (source = its PBS backup).
#
#   refresh-template.sh <NEWID> <IP> <VMNAME> [--snapshot <pbs volid>] [--scripts <dir>]
#
#   NEWID      free VMID (e.g. 115)          IP  free 192.168.12.x
#   VMNAME     e.g. logship-template-3
#   --snapshot default: newest `pvesm list pbs-logyou --vmid 105`
#   --scripts  dir with the cleanup scripts, default /tmp/tc
#              (scp reference/template-cleanup/* root@prox2:/tmp/tc/ first)
#
# Afterwards (over SSH, see REFRESH-QUICKSTART.md):
#   ssh-keygen -R <IP>; ssh root@<IP> 'cd /root/idempiere-elastic && docker compose up -d'
#   /root/template-cleanup/run-cleanup.sh   (then validate-template.sh, finalize)
# =====================================================================
set -euo pipefail

SRC_VMID=105; PBS=pbs-logyou; STORAGE=Disk1-NVMe; GW=192.168.12.1; BRIDGE=vmbr1
SCRIPTS=/tmp/tc; SNAP=""

[ $# -ge 3 ] || { grep '^#   ' "$0" | sed 's/^#  //'; exit 1; }
NEWID="$1"; IP="$2"; VMNAME="$3"; shift 3
while [ $# -gt 0 ]; do
  case "$1" in
    --snapshot) SNAP="$2"; shift 2;;
    --scripts)  SCRIPTS="$2"; shift 2;;
    *) echo "unknown option $1" >&2; exit 1;;
  esac
done

# --- preflight ------------------------------------------------------------
if qm status "$NEWID" >/dev/null 2>&1; then echo "FATAL: VMID $NEWID exists" >&2; exit 1; fi
if ping -c1 -W1 "$IP" >/dev/null 2>&1; then echo "FATAL: $IP answers ping" >&2; exit 1; fi
if grep -rqE "ip=${IP}/" /etc/pve/qemu-server/ 2>/dev/null; then echo "FATAL: $IP configured on another VM" >&2; exit 1; fi
for f in 00-defuse.sh 01-idempiere-truncate.sql 02-strapi-truncate.sql 03-neutralize-env.sh \
         04-set-instance-identity.sh run-cleanup.sh diagnose-survivors.sql validate-template.sh \
         README.md TEMPLATE-README.md RECLONE-RUNBOOK.md REFRESH-QUICKSTART.md; do
  [ -f "$SCRIPTS/$f" ] || { echo "FATAL: $SCRIPTS/$f missing — scp reference/template-cleanup/* first" >&2; exit 1; }
done
[ -n "$SNAP" ] || SNAP=$(pvesm list "$PBS" --vmid "$SRC_VMID" | tail -1 | awk '{print $1}')
[ -n "$SNAP" ] || { echo "FATAL: no PBS snapshot found" >&2; exit 1; }

echo "== $(date '+%F %T') restoring $SNAP -> VM $NEWID ($VMNAME, $IP)"
qmrestore "$SNAP" "$NEWID" --storage "$STORAGE" --unique 1
qm set "$NEWID" --name "$VMNAME" --onboot 0 --protection 0 --ipconfig0 "ip=${IP}/24,gw=${GW}"
MAC=$(qm config "$NEWID" | grep "^net0:" | sed -E "s/.*virtio=([^,]+).*/\1/")
qm set "$NEWID" --net0 "virtio=${MAC},bridge=${BRIDGE},link_down=1"   # keep the MAC!
qm start "$NEWID"
echo "== $(date '+%F %T') booted quarantined (link_down), waiting for guest agent"
for i in $(seq 1 40); do qm agent "$NEWID" ping >/dev/null 2>&1 && break; sleep 10
  [ "$i" = 40 ] && { echo "FATAL: guest agent not up after 400 s" >&2; exit 1; }; done

# --- copy scripts in (base64: pvesh file-write chokes on UTF-8) -------------
gexec() {  # gexec <timeout> <bash -c string>  -> prints out/err, returns exit code
  qm guest exec "$NEWID" --timeout "$1" -- bash -c "$2" | python3 -c '
import sys,json; d=json.load(sys.stdin)
print(d.get("out-data",""), end=""); print(d.get("err-data",""), end="", file=sys.stderr)
sys.exit(d.get("exitcode",1))'
}
gexec 30 "mkdir -p /root/template-cleanup"
for f in "$SCRIPTS"/*; do
  b=$(basename "$f")
  pvesh create "/nodes/$(hostname)/qemu/$NEWID/agent/file-write" \
    --file "/root/template-cleanup/$b.b64" --content "$(base64 -w0 "$f")"
  gexec 30 "base64 -d /root/template-cleanup/$b.b64 > /root/template-cleanup/$b && rm /root/template-cleanup/$b.b64"
done
echo "== scripts copied"

echo "== 00-defuse.sh"
gexec 900 "chmod +x /root/template-cleanup/*.sh; /root/template-cleanup/00-defuse.sh"
echo "== 03-neutralize-env.sh $IP"
gexec 120 "/root/template-cleanup/03-neutralize-env.sh $IP"
echo "== offline checks"
gexec 30 "echo host=\$(hostname); echo crontab=\$(crontab -l 2>/dev/null | grep -cE '^[^#]' || true); echo postfix=\$(systemctl is-enabled postfix 2>&1); echo hosts_logship=\$(grep -c logship.de /etc/hosts)"

qm set "$NEWID" --net0 "virtio=${MAC},bridge=${BRIDGE}"
echo "== $(date '+%F %T') NIC up. Next, from your machine:"
echo "   ssh-keygen -R $IP"
echo "   ssh root@$IP 'cd /root/idempiere-elastic && docker compose up -d'"
echo "   ssh root@$IP 'nohup /root/template-cleanup/run-cleanup.sh > /root/template-cleanup/cleanup.log 2>&1 &'"
