#!/usr/bin/env bash
# =====================================================================
# Create a new LogShip instance from the golden template (VM 113)
# ---------------------------------------------------------------------
# Runs ON prox2 (needs qm). One command: clone -> IP -> boot -> rebrand.
#
#   clone-logship-instance.sh <NEWID> <IP> "<ClientName>" \
#       ["<OrgName>"] ["<CompanyLegalName>"] \
#       [--name <vmname>] [--memory <MB>] [--cores <N>] [--domain <fqdn>]
#
#   --domain  public domain (e.g. app.blut24.com): instance public URLs
#             become https://<fqdn> (STRAPIPUBLIC, WebAuthn). DNS + TLS
#             proxy to <IP> must be set up separately. Without --domain,
#             public URLs use http://<IP>.
#
#   NEWID            free Proxmox VMID (e.g. 114)
#   IP               free IP in 192.168.12.0/24 (gw .1 assumed)
#   ClientName       tenant name (e.g. "Acme Fulfillment")
#   OrgName          default: ClientName
#   CompanyLegalName default: ClientName (linked partner, e.g. "Acme GmbH")
#   --name           VM name; default: client name slugified (acme-fulfillment)
#   --memory/--cores default: inherited from template (20480 MB / 8)
#
# After it finishes, the instance still needs (see TEMPLATE-README.md):
#   .env endpoints+credentials, iDempiere REST secret rotation, own users,
#   crons from /root/crontab.production.bak, postfix/SMTP if mail wanted.
# =====================================================================
set -euo pipefail

TEMPLATE_ID=113
GW=192.168.12.1
BRIDGE=vmbr1

usage() { grep '^#   ' "$0" | sed 's/^#  //'; exit 1; }
[ $# -ge 3 ] || usage

NEWID="$1"; IP="$2"; CLIENT="$3"; shift 3
ORG=""; COMPANY=""; VMNAME=""; MEMORY=""; CORES=""; DOMAIN=""
while [ $# -gt 0 ]; do
  case "$1" in
    --name)   VMNAME="$2"; shift 2;;
    --memory) MEMORY="$2"; shift 2;;
    --cores)  CORES="$2";  shift 2;;
    --domain) DOMAIN="$2"; shift 2;;
    --*)      echo "unknown option $1" >&2; usage;;
    *)  if   [ -z "$ORG" ];     then ORG="$1"
        elif [ -z "$COMPANY" ]; then COMPANY="$1"
        else echo "unexpected argument: $1" >&2; usage; fi
        shift;;
  esac
done
ORG="${ORG:-$CLIENT}"
COMPANY="${COMPANY:-$CLIENT}"
VMNAME="${VMNAME:-$(echo "$CLIENT" | tr '[:upper:] ' '[:lower:]-' | tr -cd 'a-z0-9-')}"

# --- preflight ------------------------------------------------------------
qm status "$TEMPLATE_ID" >/dev/null || { echo "FATAL: template VM $TEMPLATE_ID missing" >&2; exit 1; }
qm status "$TEMPLATE_ID" | grep -q stopped || { echo "FATAL: template VM $TEMPLATE_ID is running — stop it first (it must stay pristine)" >&2; exit 1; }
if qm status "$NEWID" >/dev/null 2>&1; then echo "FATAL: VMID $NEWID already exists" >&2; exit 1; fi
if ping -c1 -W1 "$IP" >/dev/null 2>&1; then echo "FATAL: $IP answers ping — pick a free IP" >&2; exit 1; fi
if grep -rqE "ip=${IP}/" /etc/pve/qemu-server/ 2>/dev/null; then
  echo "FATAL: $IP already configured on another VM" >&2; exit 1
fi

PUBLIC_TARGET="${DOMAIN:-$IP}"

echo "== Cloning template $TEMPLATE_ID -> VM $NEWID ($VMNAME), IP $IP"
echo "   client='$CLIENT'  org='$ORG'  company='$COMPANY'  public='$PUBLIC_TARGET'"

# --- clone + configure ----------------------------------------------------
qm clone "$TEMPLATE_ID" "$NEWID" --name "$VMNAME" --full
qm set "$NEWID" --ipconfig0 "ip=${IP}/24,gw=${GW}" --onboot 1
[ -n "$MEMORY" ] && qm set "$NEWID" --memory "$MEMORY"
[ -n "$CORES" ]  && qm set "$NEWID" --cores "$CORES"

qm start "$NEWID"
echo "== Waiting for guest agent..."
for i in $(seq 1 30); do
  qm agent "$NEWID" ping >/dev/null 2>&1 && break
  [ "$i" = 30 ] && { echo "FATAL: guest agent not up after 5 min" >&2; exit 1; }
  sleep 10
done

echo "== Waiting for PostgreSQL in guest..."
for i in $(seq 1 30); do
  if qm guest exec "$NEWID" -- sudo -u postgres pg_isready >/dev/null 2>&1; then break; fi
  [ "$i" = 30 ] && { echo "FATAL: postgres not ready after 5 min" >&2; exit 1; }
  sleep 10
done

echo "== Pointing instance .env public URLs at ${PUBLIC_TARGET}..."
qm guest exec "$NEWID" --timeout 120 -- \
  /root/template-cleanup/03-neutralize-env.sh "$PUBLIC_TARGET"

echo "== Rebranding tenant inside the guest..."
qm guest exec "$NEWID" --timeout 300 -- \
  /root/template-cleanup/04-set-instance-identity.sh "$CLIENT" "$ORG" "$COMPANY"

cat <<EOF

== DONE ==
VM $NEWID ($VMNAME) is up at http://${IP}:3001 (tenant '$CLIENT').
Logins/passwords = production state at template-build time.
$( [ -n "$DOMAIN" ] && cat <<D
Public URLs are set to https://${DOMAIN} — still needed externally:
  DNS ${DOMAIN} -> public IP, and a TLS-terminating proxy vhost
  forwarding to ${IP}:3001 (app) and ${IP}:80 (/api/v1, /media-api,
  /custom-api, media root) — mirror the app.logship.de vhost.
D
)

Still manual (see /root/TEMPLATE-README.md in the guest):
  1. /opt/erp-nuxt-frontend/.env — endpoints + credentials, then:
       pm2 restart erpfrontend --update-env
  2. Rotate iDempiere REST secret (prod tokens work until you do!)
  3. Replace staff users/emails, set own SuperUser password
  4. Re-enable wanted crons from /root/crontab.production.bak
  5. Mail: systemctl enable --now postfix + iDempiere SMTP config
EOF
