#!/usr/bin/env bash
set -euo pipefail

ROOT="$(cd "$(dirname "$0")/.." && pwd)"
E2E_REMOTE_SOURCE="$ROOT/bin/e2e-remote"
TMP="$(mktemp -d)"
trap 'rm -rf "$TMP"' EXIT
HOME_FIXTURE="$TMP/home"
DEPLOY_FIXTURE="$TMP/deploy/modules/workstation/claude"
mkdir -p "$HOME_FIXTURE/.claude/bin" "$TMP/shims" "$DEPLOY_FIXTURE/bin" "$DEPLOY_FIXTURE/lib"
cp "$E2E_REMOTE_SOURCE" "$DEPLOY_FIXTURE/bin/e2e-remote"
cp "$ROOT/lib/buildbox-registry.mjs" "$DEPLOY_FIXTURE/lib/buildbox-registry.mjs"
cp "$ROOT/lib/e2e-pair.sh" "$DEPLOY_FIXTURE/lib/e2e-pair.sh"
cp "$ROOT/lib/fleet-seat.sh" "$DEPLOY_FIXTURE/lib/fleet-seat.sh"
cp "$ROOT/lib/seat-attest.sh" "$DEPLOY_FIXTURE/lib/seat-attest.sh"
E2E_REMOTE="$DEPLOY_FIXTURE/bin/e2e-remote"
# shellcheck source=../lib/e2e-pair.sh
. "$ROOT/lib/e2e-pair.sh"

if ! (set +e; e2e_remote_run "" 1 "" "" bash -c 'exit 4'; rc=$?; [[ "$rc" -eq 4 && "$E2E_REMOTE_OUTCOME" == client ]]); then
  echo "FAIL: no-server client outcome was not preserved" >&2
  exit 1
fi
if ! (set +e; e2e_remote_run 41987 2 'exit 1' "" true; rc=$?; [[ "$rc" -eq 4 && "$E2E_REMOTE_OUTCOME" == admission ]]); then
  echo "FAIL: pre-ready server failure was not classified as admission" >&2
  exit 1
fi

cat >"$HOME_FIXTURE/.claude/build-remote.json" <<'JSON'
{"enabled":true,"local_fallback":true}
JSON
cat >"$HOME_FIXTURE/.claude/buildbox-hosts.json" <<'JSON'
{
  "schema_version": 1,
  "hosts": [
    {"name":"box1","ssh_alias":"box1","state":"reachable","machine_id":null,"roles":["builder","e2e"],"access":{"lan":null,"tailscale_ip":{"host":"100.64.0.1","port":22,"user":"user","identity_file":null},"tailscale_ssh":null},"rustdesk":null,"notes":"test fixture"},
    {"name":"box2","ssh_alias":"box2","state":"reachable","machine_id":null,"roles":["builder"],"access":{"lan":null,"tailscale_ip":{"host":"100.64.0.2","port":22,"user":"user","identity_file":null},"tailscale_ssh":null},"rustdesk":null,"notes":"test fixture"}
  ],
  "orders": {"build":["box1","box2"],"e2e":["box1"]}
}
JSON
cat >"$HOME_FIXTURE/.claude/bin/local-gate" <<'SH'
#!/usr/bin/env bash
case " $* " in
  *" --remote-only "*) ;;
  *) echo "missing --remote-only" >&2; exit 91 ;;
esac
args=("$@")
separator=-1
for i in "${!args[@]}"; do
  if [[ "${args[$i]}" == -- ]]; then separator=$i; break; fi
done
(( separator >= 0 )) || { echo "missing command separator" >&2; exit 92; }
payload_command="${args[$((separator + 1))]:-}"
payload_b64="${args[$((separator + 2))]:-}"
admission_hints=("${args[@]:$((separator + 3))}")
case "$payload_command" in
  /home/user/.rb/e2e-remote-payload) ;;
  *) echo "payload command is not installed remote runner: $payload_command" >&2; exit 92 ;;
esac
[[ -n "$payload_b64" ]] || { echo "payload missing" >&2; exit 93; }
if [[ -n "${E2E_HINTS:-}" ]]; then
  printf '%s\n' "${admission_hints[@]}" >"$E2E_HINTS"
fi
cp "$BUILD_REMOTE_CONFIG" "$E2E_CAPTURE"
host="$(node -e 'const fs=require("node:fs"); process.stdout.write(JSON.parse(fs.readFileSync(process.argv[1], "utf8")).dispatch_hosts[0])' "$BUILD_REMOTE_CONFIG")"
[[ -z "${E2E_ATTEMPTS:-}" ]] || printf '%s\n' "$host" >> "$E2E_ATTEMPTS"
if [[ -n "${E2E_KEYS:-}" ]]; then
  while [[ $# -gt 0 ]]; do
    if [[ "$1" == --key ]]; then printf '%s\n' "$2" >>"$E2E_KEYS"; break; fi
    shift
  done
fi
status=0
outcome=client
if [[ "$host" == "${E2E_FAIL_HOST:-}" ]]; then
  status="${E2E_FAIL_STATUS:-97}"
  outcome="${E2E_FAIL_OUTCOME:-client}"
fi
printf '%s\t%s\n' "$outcome" "$status" >"$E2E_REMOTE_RECEIPT"
exit "$status"
SH
chmod +x "$HOME_FIXTURE/.claude/bin/local-gate"

HOME="$HOME_FIXTURE" DEPLOY_FIXTURE_PATH="$DEPLOY_FIXTURE" E2E_CAPTURE="$TMP/config.json" "$E2E_REMOTE" --hosts box1 -- true

: >"$TMP/hints"
HOME="$HOME_FIXTURE" DEPLOY_FIXTURE_PATH="$DEPLOY_FIXTURE" E2E_CAPTURE="$TMP/config.json" \
  E2E_HINTS="$TMP/hints" "$E2E_REMOTE" --hosts box1 -- /bin/true nested/tests
[[ "$(<"$TMP/hints")" == $'/bin/true\nnested/tests' ]] || {
  echo "FAIL: client argv was not exposed as package-owner admission hints" >&2
  cat "$TMP/hints" >&2
  exit 1
}

PAYLOAD_B64_TEST="$(printf 'exit 0\n' | base64 -w0)"
/usr/bin/node "$ROOT/bin/e2e-remote-payload" "$PAYLOAD_B64_TEST" nested/tests settings.spec.js

: >"$TMP/keys"
for _ in 1 2; do
  HOME="$HOME_FIXTURE" DEPLOY_FIXTURE_PATH="$DEPLOY_FIXTURE" E2E_CAPTURE="$TMP/config.json" \
    E2E_KEYS="$TMP/keys" "$E2E_REMOTE" --hosts box1 -- true
done
mapfile -t dedupe_keys <"$TMP/keys"
[[ "${#dedupe_keys[@]}" -eq 2 && "${dedupe_keys[0]}" == "${dedupe_keys[1]}" ]] || {
  echo "FAIL: receipt identity changed the semantic dedupe key" >&2
  exit 1
}

: >"$TMP/attempts"
HOME="$HOME_FIXTURE" DEPLOY_FIXTURE_PATH="$DEPLOY_FIXTURE" E2E_CAPTURE="$TMP/config.json" \
  E2E_ATTEMPTS="$TMP/attempts" E2E_FAIL_HOST=box1 E2E_FAIL_STATUS=4 E2E_FAIL_OUTCOME=admission \
  "$E2E_REMOTE" --hosts box1,box2 -- true
[[ "$(<"$TMP/attempts")" == $'box1\nbox2' ]] || {
  echo "FAIL: occupied first E2E seat did not spill in registry order" >&2
  exit 1
}
node -e '
  const fs = require("node:fs");
  const config = JSON.parse(fs.readFileSync(process.argv[1], "utf8"));
  if (JSON.stringify(config.dispatch_hosts) !== JSON.stringify(["box2"])) {
    throw new Error(`final attempt did not pin the second seat: ${JSON.stringify(config.dispatch_hosts)}`);
  }
' "$TMP/config.json"

for client_rc in 3 4 5 83 84 85 97; do
  : >"$TMP/attempts"
  if HOME="$HOME_FIXTURE" DEPLOY_FIXTURE_PATH="$DEPLOY_FIXTURE" E2E_CAPTURE="$TMP/config.json" \
    E2E_ATTEMPTS="$TMP/attempts" E2E_FAIL_HOST=box1 E2E_FAIL_STATUS="$client_rc" \
    "$E2E_REMOTE" --hosts box1,box2 -- true; then
    observed=0
  else
    observed=$?
  fi
  [[ "$observed" -eq "$client_rc" ]] || {
    echo "FAIL: client exit $client_rc changed to $observed" >&2
    exit 1
  }
  [[ "$(<"$TMP/attempts")" == "box1" ]] || {
    echo "FAIL: client exit $client_rc incorrectly spilled to another host" >&2
    exit 1
  }
done

printf '{' >"$HOME_FIXTURE/.claude/build-remote.json"
: >"$TMP/attempts"
if HOME="$HOME_FIXTURE" DEPLOY_FIXTURE_PATH="$DEPLOY_FIXTURE" E2E_CAPTURE="$TMP/config.json" \
  E2E_ATTEMPTS="$TMP/attempts" "$E2E_REMOTE" --hosts box1,box2 -- true 2>"$TMP/err"; then
  echo "FAIL: invalid dispatch config must fail" >&2
  exit 1
fi
[[ ! -s "$TMP/attempts" ]] || {
  echo "FAIL: invalid pinned config reached local-gate" >&2
  exit 1
}
printf '%s\n' '{"enabled":true,"local_fallback":true}' >"$HOME_FIXTURE/.claude/build-remote.json"

if HOME="$HOME_FIXTURE" DEPLOY_FIXTURE_PATH="$DEPLOY_FIXTURE" E2E_CAPTURE="$TMP/config.json" "$E2E_REMOTE" -- true >"$TMP/out" 2>"$TMP/err"; then
  echo "FAIL: default differing e2e/build host sets must fail closed" >&2
  exit 1
fi
grep -q 'un-pinned dispatch' "$TMP/err" || {
  cat "$TMP/err" >&2
  echo "FAIL: default host mismatch diagnostic missing" >&2
  exit 1
}

if HOME="$HOME_FIXTURE" DEPLOY_FIXTURE_PATH="$DEPLOY_FIXTURE" E2E_CAPTURE="$TMP/config.json" "$E2E_REMOTE" --hosts missing -- true >"$TMP/out" 2>"$TMP/err"; then
  echo "FAIL: registry-rejected explicit host must fail closed" >&2
  exit 1
fi
grep -q -- '--hosts rejected by the buildbox registry' "$TMP/err" || {
  cat "$TMP/err" >&2
  echo "FAIL: registry rejection diagnostic missing" >&2
  exit 1
}

cat >"$HOME_FIXTURE/.claude/buildbox-hosts.json" <<'JSON'
{
  "schema_version": 1,
  "hosts": [
    {"name":"box1","ssh_alias":"box1","state":"reachable","machine_id":null,"roles":["builder","e2e"],"access":{"lan":null,"tailscale_ip":{"host":"100.64.0.1","port":22,"user":"user","identity_file":null},"tailscale_ssh":null},"rustdesk":null,"notes":"test fixture"}
  ],
  "orders": {"build":["box1"],"e2e":["box1"]}
}
JSON
cat >"$TMP/shims/node" <<'SH'
#!/usr/bin/env bash
if [[ " $* " == *" hosts --order build "* ]]; then
  echo "PATH node shim offloaded registry lookup" >&2
  exit 97
fi
exec /usr/bin/node "$@"
SH
chmod +x "$TMP/shims/node"

PATH="$TMP/shims:$PATH" HOME="$HOME_FIXTURE" DEPLOY_FIXTURE_PATH="$DEPLOY_FIXTURE" E2E_CAPTURE="$TMP/config.json" "$E2E_REMOTE" -- true
node -e '
  const fs = require("node:fs");
  const config = JSON.parse(fs.readFileSync(process.argv[1], "utf8"));
  if ("hosts" in config) throw new Error("generated config contains obsolete hosts key");
  if (config.local_fallback !== false) throw new Error("generated config permits local fallback");
  if (JSON.stringify(config.dispatch_hosts) !== JSON.stringify(["box1"])) {
    throw new Error(`generated config does not pin dispatch hosts: ${JSON.stringify(config.dispatch_hosts)}`);
  }
' "$TMP/config.json"

echo "e2e-remote config tests passed"
