#!/usr/bin/env bash
# verify-deployed.sh — does the estate actually RUN the code we have committed?
#
# WHY THIS EXISTS (2026-07-11). Every serious failure found this session shared one
# shape: something was asserted and never verified. The sharpest instance was the
# gap between *committed* and *deployed*:
#   · the backup scripts had carried a heartbeat since f63c608 — the hosts ran older
#     copies with NO heartbeat at all, for weeks (PAPER-03)
#   · `pull-backups.sh`, the off-host mirror — the single thing standing between us
#     and single-VM data loss — was not in git AT ALL; it existed only on agent2
#     (PAPER-06)
#   · the committed `backups/*.sh` still differ from the live ones in BACKUP_DIR and
#     dump method; deploying them blindly would have relocated every backup (PAPER-05)
# "Recipes as code" that nobody deploys is fiction, and worse than fiction: it invites
# a confident, wrong deploy. This makes the gap VISIBLE instead of assumed.
#
# It compares the sha256 of each canonical file in this repo against the file actually
# on the host. KNOWN, RECORDED divergences are listed explicitly with their paper —
# a divergence we have *decided* is different from one we have *not noticed*. Anything
# else is reported as DRIFT.
#
#   usage: ops/verify-deployed.sh [--key <ssh-key>]        exit 0 = in sync, 1 = drift
set -uo pipefail

KEY="${SSH_KEY:-$HOME/PycharmProjects/mgf/my_stuff/infomaniak/woodpecker_id_ed25519}"
[ "${1:-}" = "--key" ] && { KEY="$2"; shift 2; }
REPO="$(cd "$(dirname "$0")/.." && pwd)"
SSH="ssh -i $KEY -o ConnectTimeout=15 -o StrictHostKeyChecking=accept-new"

WP=195.15.241.48; DEVPI=195.15.203.250; OO=195.15.203.114; A2=195.15.203.243

# repo-file : host : deployed-path
TRACKED=(
  "ops/self-heal.sh:$WP:/opt/woodpecker/self-heal.sh"
  "ops/self-heal.sh:$A2:/opt/woodpecker-agent/self-heal.sh"
  "ops/agent-reconciler.py:$WP:/opt/woodpecker/agent-reconciler.py"
  "ops/pull-backups.sh:$A2:/opt/watcher/pull-backups.sh"
  "ops/estate-watch-heartbeats.sh:$A2:/opt/watcher/estate-watch-heartbeats.sh"
  "backups/config-snapshot-nightly.sh:$WP:/opt/backups/config-snapshot-nightly.sh"
  "backups/config-snapshot-nightly.sh:$DEVPI:/opt/backups/config-snapshot-nightly.sh"
  "backups/config-snapshot-nightly.sh:$OO:/opt/backups/config-snapshot-nightly.sh"
  "backups/config-snapshot-nightly.sh:$A2:/opt/backups/config-snapshot-nightly.sh"
  # PAPER-05 RESOLVED 2026-07-11 (founder option a): the repo's safer scripts were
  # reconciled to /opt/backups + docker-exec and DEPLOYED to the hosts (each manually
  # run-verified: pg 27M · oo 39M+restart · devpi 63M+restart+serving), so repo==deployed
  # and these are now byte-tracked like everything else.
  "backups/pg-dump-nightly.sh:$WP:/opt/backups/pg-dump-nightly.sh"
  "backups/devpi-export-nightly.sh:$DEVPI:/opt/backups/devpi-export-nightly.sh"
  "backups/oo-snapshot-nightly.sh:$OO:/opt/backups/oo-snapshot-nightly.sh"
)

# Divergences we have DECIDED on, not ones we failed to notice. Each carries its paper.
# (PAPER-05 resolved 2026-07-11 → its three entries graduated into TRACKED above.)
KNOWN_DIVERGED=()

drift=0
echo "=== deployed vs committed ==="
for spec in "${TRACKED[@]}"; do
  f="${spec%%:*}"; rest="${spec#*:}"; host="${rest%%:*}"; path="${rest#*:}"
  [ -f "$REPO/$f" ] || { echo "  ✗ $f — NOT IN REPO (the PAPER-06 class: it exists only on the host)"; drift=1; continue; }
  want=$(sha256sum "$REPO/$f" | cut -c1-12)
  got=$($SSH "ubuntu@$host" "sudo sha256sum $path 2>/dev/null | cut -c1-12" 2>/dev/null)
  if [ -z "$got" ]; then
    echo "  ✗ $f → $host:$path — NOT DEPLOYED (committed, but the host never got it)"; drift=1
  elif [ "$want" = "$got" ]; then
    echo "  ✓ $f → $host:$path"
  else
    echo "  ✗ $f → $host:$path — DRIFT (repo $want ≠ host $got)"; drift=1
  fi
done

echo "=== known, recorded divergences (decided — not unnoticed) ==="
for spec in "${KNOWN_DIVERGED[@]}"; do
  f="${spec%%:*}"; rest="${spec#*:}"; host="${rest%%:*}"; rest2="${rest#*:}"
  path="${rest2%%:*}"; why="${rest2#*:}"
  got=$($SSH "ubuntu@$host" "sudo sha256sum $path >/dev/null 2>&1 && echo present" 2>/dev/null)
  echo "  ~ $f → $host:$path — ${got:-MISSING} · $why"
done

[ "$drift" -eq 0 ] && echo "IN SYNC — every tracked script on the estate matches the repo." \
                   || echo "DRIFT — the estate is not running the code we think it is."
exit "$drift"
