#!/usr/bin/env bash
# Seed (or re-seed) an encrypted secrets file from an environment's live env file.
# Run on the operator's machine — it reads production secrets, so it is deliberately
# NOT something the agent runs for you. Requires: sops + age on PATH, the age private
# key at ~/.config/sops/age/keys.txt (or SOPS_AGE_KEY_FILE), and SSH access to the box.
#
#   deploy/secrets/seed-from-live.sh prod agent@169.58.46.181 ~/.ssh/thermograph_agent_ed25519
#   deploy/secrets/seed-from-live.sh beta agent@169.58.46.181 ~/.ssh/thermograph_agent_ed25519
#   deploy/secrets/seed-from-live.sh dev  agent@75.119.132.91 ~/.ssh/thermograph_agent_ed25519
#
# Note prod and beta share a box (vps2) and therefore differ only by which env
# FILE is read: /etc/thermograph.env vs /etc/thermograph-beta.env. That path is
# resolved from deploy/env-topology.sh rather than hardcoded — hardcoding it
# meant "seed beta" would read PROD's live secrets and write them into
# beta.yaml, which is how one environment silently ends up holding another's
# credentials.
#
# Writes deploy/secrets/<env>.yaml ENCRYPTED (exact copy of the live env, so the
# deploy render is faithful), then verifies the render round-trips to the same
# KEY=VALUE set. Never prints secret values. See README.md.
set -euo pipefail

# Anchor to the repo that holds this script, so it works when invoked by absolute path
# from any cwd (a different checkout, your home dir, etc.) — OUT and .sops.yaml resolve
# relative to here, not to wherever you happened to run it.
cd "$(dirname "$(readlink -f "$0")")/../.."

ENV_NAME="${1:?usage: seed-from-live.sh <env> <ssh-target> [ssh-key]}"
SSH_TARGET="${2:?ssh target, e.g. agent@169.58.46.181}"
SSH_KEY="${3:-$HOME/.ssh/thermograph_agent_ed25519}"
OUT="deploy/secrets/${ENV_NAME}.yaml"
# shellcheck source=infra/deploy/env-topology.sh
. deploy/env-topology.sh
thermograph_topology "$ENV_NAME"
REMOTE_ENV_FILE="$TG_ENV_FILE"
command -v sops >/dev/null || { echo "!! sops not on PATH" >&2; exit 1; }

tmp="$(mktemp)"; trap 'rm -f "$tmp" "$tmp.env"' EXIT
umask 077

echo "==> Pulling ${SSH_TARGET}:${REMOTE_ENV_FILE} (sudo)"
ssh -i "$SSH_KEY" "$SSH_TARGET" "sudo cat $REMOTE_ENV_FILE" > "$tmp"
n=$(grep -cE '^[A-Za-z_][A-Za-z0-9_]*=' "$tmp" || true)
[ "$n" -gt 0 ] || { echo "!! no KEY=VALUE lines read (permission? path?)" >&2; exit 1; }
echo "    ${n} vars"

echo "==> Writing ${OUT} (flat YAML) and encrypting"
python3 - "$tmp" "$OUT" "$ENV_NAME" <<'PY'
import json, sys
src, dst, env = sys.argv[1:4]
pairs = {}
for line in open(src, encoding="utf-8"):
    s = line.rstrip("\n").strip()
    if not s or s.startswith("#") or "=" not in s:
        continue
    k, _, v = s.partition("=")
    k = k.strip()
    if not all(c.isalnum() or c == "_" for c in k) or not k[0].isalpha() and k[0] != "_":
        continue
    pairs[k] = v
with open(dst, "w", encoding="utf-8") as fh:
    fh.write(f"# SOPS-encrypted — {env} host secrets, seeded from that environment’s live env file.\n")
    for k, v in pairs.items():
        fh.write(f"{k}: {json.dumps(v)}\n")   # JSON-escaped scalar is valid YAML
print(f"    {len(pairs)} keys")
PY
sops -e -i "$OUT"
grep -q 'ENC\[AES256_GCM' "$OUT" || { echo "!! $OUT did not encrypt — refusing to keep it" >&2; rm -f "$OUT"; exit 1; }

echo "==> Verifying the render round-trips to the same KEY=VALUE set"
sops -d --input-type yaml --output-type dotenv "$OUT" > "$tmp.env"
python3 - "$tmp" "$tmp.env" <<'PY'
import sys
def load(p):
    d = {}
    for line in open(p, encoding="utf-8"):
        s = line.rstrip("\n").strip()
        if not s or s.startswith("#") or "=" not in s:
            continue
        k, _, v = s.partition("=")
        d[k.strip()] = v
    return d
live, rendered = load(sys.argv[1]), load(sys.argv[2])
missing = sorted(set(live) - set(rendered))
extra   = sorted(set(rendered) - set(live))
diff    = sorted(k for k in live if k in rendered and live[k] != rendered[k])
if missing or extra or diff:
    if missing: print("   !! keys lost in render:", missing)
    if extra:   print("   !! keys added in render:", extra)
    if diff:    print("   !! values changed (keys only):", diff)
    sys.exit(1)
print(f"   OK — {len(live)} keys render identically")
PY
echo "==> ${OUT} is ready. Review with:  sops ${OUT}   (or git diff --stat)"
echo "    Then commit + push; the agent can take it from there."
