#!/usr/bin/env bash
# The guard blocks where a browser does not belong, not where it lacks a marker.
# Everything here runs against fake browser binaries — no headless browser is launched.
set -uo pipefail

ROOT="$(cd "$(dirname "$0")/.." && pwd)"
GUARD="$ROOT/bin/install-headless-guard"
TMP="$(mktemp -d)"
trap 'rm -rf "$TMP"' EXIT

SELF_MID="$(cat /etc/machine-id 2>/dev/null)"
[ -n "$SELF_MID" ] || { echo "FAIL: /etc/machine-id is empty; cannot test host identity" >&2; exit 1; }
OTHER_MID="0123456789abcdef0123456789abcdef"

fail() { echo "FAIL: $*" >&2; exit 1; }
ok() { echo "OK: $*"; }

registry() { # machine_id -> path
  local mid=$1
  local path="$TMP/registry-$mid.json"
  cat >"$path" <<JSON
{
  "schema_version": 1,
  "hosts": [
    {
      "name": "testbox",
      "ssh_alias": "testbox",
      "state": "reachable",
      "machine_id": "$mid",
      "roles": ["builder", "e2e"],
      "access": {
        "lan": null,
        "tailscale_ip": { "host": "100.64.0.1", "port": 2222, "user": "user", "identity_file": null },
        "tailscale_ssh": null
      },
      "rustdesk": null,
      "notes": "fixture"
    }
  ],
  "orders": { "build": ["testbox"] }
}
JSON
  echo "$path"
}

BINS=(
  "chromium_headless_shell-1/chrome-headless-shell-linux64/chrome-headless-shell"
  "firefox-1/firefox/firefox"
  "webkit-1/pw_run.sh"
)

fixture() { # -> browser dir with fake binaries
  local dir="$1" rel
  for rel in "${BINS[@]}"; do
    mkdir -p "$dir/$(dirname "$rel")"
    printf '#!/usr/bin/bash\necho REAL-RAN "$@"\n' >"$dir/$rel"
    chmod 755 "$dir/$rel"
  done
}

RC=0
run_browser() { # dir -> combined output in $TMP/browser.out, exit status in $RC
  "$1/${BINS[0]}" --probe >"$TMP/browser.out" 2>&1
  RC=$?
}

# --- workstation identity: blocks without the marker, passes with it ----------
WS="$TMP/ws"; fixture "$WS"
out="$(BUILDBOX_HOSTS_CONFIG="$(registry "$OTHER_MID")" "$GUARD" --dir "$WS" 2>&1)" || fail "install failed: $out"
echo "$out" | grep -q "mode=blocking identity=workstation" || fail "workstation install line: $out"
echo "  $out"

run_browser "$WS"
[ "$RC" = 97 ] || fail "workstation launch should exit 97, got $RC"
grep -q "^BLOCKED: chrome-headless-shell may not run on this machine.$" "$TMP/browser.out" \
  || fail "no BLOCKED banner: $(cat "$TMP/browser.out")"
ok "workstation blocks (exit 97)"
grep -A2 "This host is not a buildbox" "$TMP/browser.out" | sed 's/^/  | /'

out="$(E2E_REMOTE_OK=1 "$WS/${BINS[0]}" --probe 2>&1)"; rc=$?
[ "$rc" = 0 ] && [ "$out" = "REAL-RAN --probe" ] || fail "E2E_REMOTE_OK escape hatch broken: rc=$rc out=$out"
ok "workstation passes with E2E_REMOTE_OK=1 -> $out"

out="$(BUILDBOX_HOSTS_CONFIG="$(registry "$OTHER_MID")" "$GUARD" --dir "$WS" --status 2>&1)" || fail "status should be clean: $out"
echo "  $out"
ok "--status clean on a freshly wrapped workstation"

# --- buildbox identity: passes with no marker at all -------------------------
BB="$TMP/bb"; fixture "$BB"
out="$(BUILDBOX_HOSTS_CONFIG="$(registry "$SELF_MID")" "$GUARD" --dir "$BB" 2>&1)" || fail "install failed: $out"
echo "$out" | grep -q "mode=pass-through identity=buildbox testbox (via machine-id)" || fail "buildbox install line: $out"
echo "  $out"

for rel in "${BINS[@]}"; do
  out="$("$BB/$rel" --probe 2>&1)"; rc=$?
  [ "$rc" = 0 ] && [ "$out" = "REAL-RAN --probe" ] || fail "buildbox launch of $rel blocked: rc=$rc out=$out"
done
ok "buildbox passes every wrapped engine with no E2E_REMOTE_OK -> REAL-RAN"

# --- indeterminate identity: blocks ------------------------------------------
printf '{ "schema_version": 1, "hosts": [\n' >"$TMP/truncated.json"
for reg in "$TMP/nonexistent.json" "$TMP/truncated.json"; do
  D="$TMP/ind-$(basename "$reg")"; fixture "$D"
  out="$(BUILDBOX_HOSTS_CONFIG="$reg" "$GUARD" --dir "$D" 2>&1)" || fail "install must still succeed: $out"
  echo "$out" | grep -q "mode=blocking identity=unresolved (registry unreadable)" || fail "indeterminate line for $reg: $out"
  echo "  $out"
  run_browser "$D"
  [ "$RC" = 97 ] || fail "indeterminate registry must block, got $RC"
done
ok "missing and malformed registries both block (exit 97), installer still exits 0"

# --- convergence: the body is the artifact, not the .real sibling ------------
before="$(find "$BB" -name '*' -printf '%T@ %p\n' | sort | sha256sum)"
out="$(BUILDBOX_HOSTS_CONFIG="$(registry "$SELF_MID")" "$GUARD" --dir "$BB" 2>&1)" || fail "reinstall failed: $out"
echo "$out" | grep -q "wrapped=0 refreshed=0 current=3" || fail "reinstall should be a no-op: $out"
[ "$(find "$BB" -name '*' -printf '%T@ %p\n' | sort | sha256sum)" = "$before" ] \
  || fail "no-op reinstall touched the cache (would retrigger headless-guard.path)"
ok "idempotent reinstall: current=3, cache untouched"

out="$(BUILDBOX_HOSTS_CONFIG="$(registry "$OTHER_MID")" "$GUARD" --dir "$BB" 2>&1)" || fail "reinstall failed: $out"
echo "$out" | grep -q "wrapped=0 refreshed=3 current=0" || fail "identity flip should rewrite bodies: $out"
echo "  $out"
run_browser "$BB"
[ "$RC" = 97 ] || fail "pass-through wrapper survived a flip to workstation identity, got $RC"
ok "identity flip converges an already-wrapped tree (pass-through -> blocking)"

# --- a v1 wrapper is stale, and is replaced rather than skipped --------------
V1="$TMP/v1"; fixture "$V1"
b="$V1/${BINS[0]}"
mv "$b" "$b.real"
printf '#!/usr/bin/bash\n# e2e-headless-guard v1 — DO NOT EDIT\nexit 97\n' >"$b"
chmod 755 "$b"
out="$(BUILDBOX_HOSTS_CONFIG="$(registry "$SELF_MID")" "$GUARD" --dir "$V1" --status 2>&1)" && fail "v1 wrapper should read stale: $out"
echo "$out" | grep -q "^STALE $b\$" || fail "status should name the stale wrapper: $out"
out="$(BUILDBOX_HOSTS_CONFIG="$(registry "$SELF_MID")" "$GUARD" --dir "$V1" 2>&1)" || fail "install failed: $out"
echo "$out" | grep -q "wrapped=2 refreshed=1 current=0" || fail "v1 wrapper should be rewritten: $out"
echo "  $out"
out="$("$b" --probe 2>&1)"; rc=$?
[ "$rc" = 0 ] && [ "$out" = "REAL-RAN --probe" ] || fail "rewritten v1 wrapper still blocks: rc=$rc out=$out"
ok "a v1 wrapper is reported STALE and rewritten in place"

# --- a guard with no .real sibling must never be moved onto one --------------
ORPH="$TMP/orphan"; fixture "$ORPH"
printf '#!/usr/bin/bash\n# e2e-headless-guard v2 — DO NOT EDIT\nexit 97\n' >"$ORPH/${BINS[0]}"
out="$(BUILDBOX_HOSTS_CONFIG="$(registry "$SELF_MID")" "$GUARD" --dir "$ORPH" 2>&1)" && fail "orphan guard must be fatal: $out"
echo "$out" | grep -q "FATAL .* is a guard with no .real sibling" || fail "orphan guard message: $out"
[ ! -e "$ORPH/${BINS[0]}.real" ] || fail "orphan guard was moved onto .real, destroying the browser"
ok "a guard with no .real sibling is refused, never moved"

# --- a real ELF target is wrapped as new, never mistaken for a guard ----------
ELF="$TMP/elf"; fixture "$ELF"
cp /usr/bin/env "$ELF/${BINS[0]}"
out="$(BUILDBOX_HOSTS_CONFIG="$(registry "$SELF_MID")" "$GUARD" --dir "$ELF" 2>&1)" || fail "ELF install failed: $out"
echo "$out" | grep -q "wrapped=3 refreshed=0 current=0" || fail "ELF target should wrap as new: $out"
cmp -s "$ELF/${BINS[0]}.real" /usr/bin/env || fail "ELF was not preserved as .real"
ok "an unwrapped ELF is wrapped as new, not read as a guard"

echo "PASS: headless-guard-scope"
