#!/usr/bin/env bash
# ============================================================================
#  Deploy the Brimoza marketing-site backend (email gate + analytics + admin)
#  to the shared production server, as an ISOLATED container next to the static
#  nginx site. Does NOT touch TopsNews, the demos stack, or the product
#  coinotomation-* containers.
#
#  Steps:
#    1. rsync site_api/ + compose.site-api.yml  ->  /opt/brimoza-site-api
#    2. ensure /opt/brimoza-site-api/.env (generate salt + admin password if missing)
#    3. docker compose -p brimoza-api up -d --build   (container brimoza-api on demos_demos)
#    4. add Caddy routes for /api/* and /admin* IN-PLACE (backup + validate + reload)
#
#  Usage:
#    bash scripts/deploy_site_api.sh            # full deploy (app + caddy)
#    bash scripts/deploy_site_api.sh --app      # app only (skip Caddy edit)
#    bash scripts/deploy_site_api.sh --caddy    # Caddy routing only
# ============================================================================
set -euo pipefail

SSH_KEY="${SSH_KEY:-$HOME/Desktop/ssh_commernix/id_ed25519}"
SERVER="${SERVER:-root@178.104.203.200}"
SSH="ssh -i $SSH_KEY $SERVER"
REMOTE_DIR="/opt/brimoza-site-api"
CADDYFILE="/opt/demos/Caddyfile"
CADDY_CT="demos-caddy-1"
HERE="$(cd "$(dirname "$0")/.." && pwd)"

DO_APP=1; DO_CADDY=1
case "${1:-}" in
  --app)   DO_CADDY=0 ;;
  --caddy) DO_APP=0 ;;
  "" )     ;;
  * ) echo "unknown arg: $1"; exit 2 ;;
esac

say(){ printf "\n\033[1;32m==>\033[0m %s\n" "$*"; }

# ---------------------------------------------------------------- 1) app deploy
if [ "$DO_APP" = 1 ]; then
  say "Syncing site_api -> $REMOTE_DIR"
  $SSH "mkdir -p $REMOTE_DIR"
  rsync -az --delete -e "ssh -i $SSH_KEY" \
    --exclude '.env' --exclude '__pycache__' --exclude '*.pyc' --exclude 'state' \
    "$HERE/site_api" "$HERE/compose.site-api.yml" "$SERVER:$REMOTE_DIR/"

  say "Ensuring .env (admin password + privacy salt)"
  $SSH "bash -s" <<'REMOTE'
set -euo pipefail
cd /opt/brimoza-site-api
gen(){ openssl rand -hex "${1:-16}"; }
if [ ! -f .env ]; then
  SALT="$(gen 16)"
  PW="$(gen 12)"
  # Salted PBKDF2 (stdlib only) — NOT a bare sha256 (which is brute-forceable if the .env leaks).
  # Format matches site_api/auth.verify_password: pbkdf2_sha256$iters$salt$hash.
  PWH="$(PW="$PW" python3 - <<'PY'
import os, hashlib, secrets
pw = os.environ["PW"].encode()
salt = secrets.token_bytes(16); iters = 240000
dk = hashlib.pbkdf2_hmac("sha256", pw, salt, iters)
print(f"pbkdf2_sha256${iters}${salt.hex()}${dk.hex()}")
PY
)"
  cat > .env <<EOF
BRIMOZA_SITE_ADMIN_USER=admin
BRIMOZA_SITE_ADMIN_PASSWORD_SHA256=$PWH
BRIMOZA_SITE_SALT=$SALT
BRIMOZA_SITE_TRUST_PROXY=1
BRIMOZA_SITE_HOSTS=brimoza.com,www.brimoza.com
BRIMOZA_DOWNLOAD_URL=/download/brimoza-latest.zip
BRIMOZA_ARTIFACT=brimoza-latest.zip
BRIMOZA_SITE_DB_URL=sqlite:////data/brimoza_site.db
EOF
  chmod 600 .env
  echo "================================================================"
  echo "  NEW ADMIN PASSWORD (store it now; only the hash is kept):"
  echo "     user: admin"
  echo "     pass: $PW"
  echo "================================================================"
else
  echo ".env already exists — keeping it."
fi
REMOTE

  say "Building & starting brimoza-api container"
  $SSH "cd $REMOTE_DIR && docker compose -p brimoza-api -f compose.site-api.yml up -d --build"
  say "Health:"
  $SSH "docker exec brimoza-api python -c \"import urllib.request;print(urllib.request.urlopen('http://127.0.0.1:8080/healthz',timeout=3).read().decode())\"" || true
fi

# ---------------------------------------------------------------- 2) caddy routes
if [ "$DO_CADDY" = 1 ]; then
  say "Adding Caddy routes for /api/* and /admin* (in-place, with backup + validate)"
  $SSH "bash -s" <<'REMOTE'
set -euo pipefail
CADDYFILE="/opt/demos/Caddyfile"
CADDY_CT="demos-caddy-1"
if grep -q "brimoza-api:8080" "$CADDYFILE"; then
  echo "Caddy already routes to brimoza-api — nothing to do."
  exit 0
fi

# SAFETY: confirm the host file we edit IS the file the container validates/reloads.
# We edit the HOST path ($CADDYFILE) but validate/reload the IN-CONTAINER path
# (/etc/caddy/Caddyfile). If they are not the same bind-mounted file, editing the host
# would silently have no effect (validate passes on the stale in-container file). Abort if so.
if ! docker exec "$CADDY_CT" cat /etc/caddy/Caddyfile 2>/dev/null | cmp -s - "$CADDYFILE"; then
  echo "ERROR: $CADDYFILE (host) differs from /etc/caddy/Caddyfile (in $CADDY_CT)." >&2
  echo "       The host file is not the one Caddy loads. Aborting — edit Caddy config manually." >&2
  exit 5
fi

TS="$(date +%Y%m%d-%H%M%S)"
cp "$CADDYFILE" "$CADDYFILE.bak-brimozaapi-$TS"
echo "Backup: $CADDYFILE.bak-brimozaapi-$TS"

# Rewrite the brimoza.com site block: route /api/* and /admin* to the API, keep
# everything else (incl. the still-public /download/*) on the static nginx.
# In-place truncate (preserves inode — Caddy watches the file).
python3 - "$CADDYFILE" <<'PY'
import re, sys
p = sys.argv[1]
src = open(p, encoding="utf-8").read()
needle = "reverse_proxy brimoza-site:80"
if needle not in src:
    sys.stderr.write("ERROR: 'reverse_proxy brimoza-site:80' not found; aborting (manual edit needed).\n")
    sys.exit(3)
if src.count(needle) != 1:
    sys.stderr.write("ERROR: expected exactly one brimoza-site reverse_proxy; found %d; aborting.\n" % src.count(needle))
    sys.exit(3)
replacement = (
    "handle /api/* {\n"
    "\t\treverse_proxy brimoza-api:8080\n"
    "\t}\n"
    "\thandle /admin* {\n"
    "\t\treverse_proxy brimoza-api:8080\n"
    "\t}\n"
    "\thandle {\n"
    "\t\treverse_proxy brimoza-site:80\n"
    "\t}"
)
src = src.replace(needle, replacement)
with open(p, "w", encoding="utf-8") as f:   # truncate-in-place keeps the inode
    f.write(src)
print("Caddyfile rewritten.")
PY

if docker exec "$CADDY_CT" caddy validate --config /etc/caddy/Caddyfile >/dev/null 2>&1; then
  docker exec "$CADDY_CT" caddy reload --config /etc/caddy/Caddyfile
  echo "Caddy validated + reloaded OK."
else
  echo "VALIDATE FAILED — restoring backup."
  cp "$CADDYFILE.bak-brimozaapi-$TS" "$CADDYFILE"
  docker exec "$CADDY_CT" caddy reload --config /etc/caddy/Caddyfile || true
  exit 4
fi
REMOTE
fi

say "Done. Admin panel: https://brimoza.com/admin"
