#!/usr/bin/env bash
# End-to-end seat hatch tests. Proves HARNESS_SEAT_REMOTE=0 cannot turn a headless
# remote seat into a local workstation dispatch, while a real terminal remains allowed.
set -uo pipefail

TEST_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$TEST_DIR/../../../.." && pwd)"
WRAPPER="$REPO_ROOT/modules/harness/wrappers/claude.sh"
REAL_GUARD="$REPO_ROOT/modules/workstation/claude/bin/local-dispatch-guard"

PASS=0 FAIL=0
ok()   { PASS=$((PASS+1)); echo "PASS $1"; }
bad()  { FAIL=$((FAIL+1)); echo "FAIL $1"; }
check(){ [[ "$2" == "$3" ]] && ok "$1 ($2)" || bad "$1: expected $3, got $2"; }

TMP="$(mktemp -d)"
trap 'rm -rf "$TMP"' EXIT

mkdir -p "$TMP/home/.claude/bin" "$TMP/bin" "$TMP/ws"
cp "$REAL_GUARD" "$TMP/home/.claude/bin/local-dispatch-guard"
chmod +x "$TMP/home/.claude/bin/local-dispatch-guard"
NODE_BIN="$(command -v node || true)"
if [[ -n "$NODE_BIN" ]]; then
  ln -s "$NODE_BIN" "$TMP/bin/node"
else
  bad 'node is available for the real seat shim'
fi

cat >"$TMP/bin/claude" <<'STUB'
#!/usr/bin/env bash
if [[ "${1:-}" == "auth" && "${2:-}" == "status" && "${3:-}" == "--json" ]]; then
  printf '%s\n' '{"status":"ok"}'
  exit 0
fi
touch "$SEAT_HATCH_SENTINEL"
printf '%s\n' '{"is_error":false,"session_id":"s","result":"ok"}'
exit 0
STUB
chmod +x "$TMP/bin/claude"

git -C "$TMP/ws" init -q
git -C "$TMP/ws" config user.name seat-hatch
git -C "$TMP/ws" config user.email seat-hatch@example.invalid
git -C "$TMP/ws" commit -q --allow-empty -m base

cp "$REPO_ROOT/modules/harness/seat/seat-remote.json" "$TMP/seat-remote-off.json"
sed -i '0,/"enabled": true/s//"enabled": false/' "$TMP/seat-remote-off.json"
cat >"$TMP/home/.claude/buildbox-hosts.json" <<'JSON'
{
  "schema_version": 1,
  "hosts": [
    {
      "name": "seat-hatch-unreachable",
      "ssh_alias": "seat-hatch-unreachable",
      "state": "reachable",
      "machine_id": null,
      "roles": ["builder"],
      "access": {
        "lan": { "host": "seat-hatch-unreachable.invalid", "port": 2222, "user": "user", "identity_file": null },
        "tailscale_ip": { "host": "seat-hatch-unreachable.invalid", "port": 2222, "user": "user", "identity_file": null },
        "tailscale_ssh": { "host": "seat-hatch-unreachable.invalid", "port": 2222, "user": "user", "identity_file": null }
      },
      "rustdesk": null,
      "notes": "seat-hatch fixture host — resolves nowhere, so a routed seat fails engine-down"
    }
  ],
  "orders": { "build": ["seat-hatch-unreachable"], "e2e": ["seat-hatch-unreachable"] }
}
JSON

cat >"$TMP/build-remote.json" <<'JSON'
{
  "enabled": true,
  "hosts": ["seat-hatch-unreachable.invalid"],
  "port": 2222,
  "ssh_user": "user",
  "remote_root": "/home/user/builds",
  "identity_file": "~/.ssh/id_ed25519_buildbox",
  "local_fallback": false,
  "local_only": [],
  "max_remote_jobs": 1
}
JSON

ARGS=(
  --workspace "$TMP/ws"
  --trust 'seat hatch fixture'
  --task-slug seat-hatch
  --model claude-3-5-sonnet
  --timeout 10
)

run_headless() {
  local config="$1" sentinel="$2" stdout="$3" stderr="$4"
  rm -f "$sentinel"
  local rc=0
  if env -i \
    HOME="$TMP/home" \
    PATH="$TMP/bin:/usr/bin:/bin" \
    HARNESS_SEAT_REMOTE=0 \
    HARNESS_SEAT_CONFIG="$config" \
    BUILD_REMOTE_CONFIG="$TMP/build-remote.json" \
    SEAT_HATCH_SENTINEL="$sentinel" \
    _CLAUDE_ENGINE_BIN="$TMP/bin/claude" \
    bash "$WRAPPER" "${ARGS[@]}" >"$stdout" 2>"$stderr"; then
    rc=0
  else
    rc=$?
  fi
  printf '%s\n' "$rc"
}

SENTINEL_A="$TMP/sentinel-a"
SENTINEL_B="$TMP/sentinel-b"
SENTINEL_C="$TMP/sentinel-c"

rc_a="$(run_headless "$REPO_ROOT/modules/harness/seat/seat-remote.json" "$SENTINEL_A" "$TMP/a.stdout" "$TMP/a.stderr")"
[[ ! -e "$SENTINEL_A" ]] && ok 'A headless HARNESS_SEAT_REMOTE=0 does not run the local engine' || bad 'A headless HARNESS_SEAT_REMOTE=0 does not run the local engine'
check 'A the seat is still routed remotely and fails engine-down' "$rc_a" 3

rc_b="$(run_headless "$TMP/seat-remote-off.json" "$SENTINEL_B" "$TMP/b.stdout" "$TMP/b.stderr")"
check 'B disabled remoting refuses headless local dispatch' "$rc_b" 97
[[ ! -e "$SENTINEL_B" ]] && ok 'B headless refusal does not run the local engine' || bad 'B headless refusal does not run the local engine'

if command -v script >/dev/null 2>&1; then
  cat >"$TMP/run-case-c.sh" <<'RUNNER'
#!/usr/bin/env bash
set -uo pipefail
exec env -i \
  HOME="$SEAT_HATCH_HOME" \
  PATH="$SEAT_HATCH_PATH" \
  HARNESS_SEAT_REMOTE=0 \
  HARNESS_SEAT_CONFIG="$SEAT_HATCH_CONFIG" \
  BUILD_REMOTE_CONFIG="$SEAT_HATCH_BUILD_CONFIG" \
  SEAT_HATCH_SENTINEL="$SEAT_HATCH_SENTINEL" \
  _CLAUDE_ENGINE_BIN="$SEAT_HATCH_ENGINE" \
  bash "$SEAT_HATCH_WRAPPER" \
    --workspace "$SEAT_HATCH_WORKSPACE" \
    --trust 'seat hatch fixture' \
    --task-slug seat-hatch \
    --model claude-3-5-sonnet \
    --timeout 10
RUNNER
  chmod +x "$TMP/run-case-c.sh"
  rm -f "$SENTINEL_C"
  rc_c=0
  if SEAT_HATCH_HOME="$TMP/home" \
    SEAT_HATCH_PATH="$TMP/bin:/usr/bin:/bin" \
    SEAT_HATCH_CONFIG="$TMP/seat-remote-off.json" \
    SEAT_HATCH_BUILD_CONFIG="$TMP/build-remote.json" \
    SEAT_HATCH_SENTINEL="$SENTINEL_C" \
    SEAT_HATCH_ENGINE="$TMP/bin/claude" \
    SEAT_HATCH_WRAPPER="$WRAPPER" \
    SEAT_HATCH_WORKSPACE="$TMP/ws" \
    script -qec "$TMP/run-case-c.sh" /dev/null >"$TMP/c.stdout" 2>"$TMP/c.stderr"; then
    rc_c=0
  else
    rc_c=$?
  fi
  check 'C pty local dispatch succeeds' "$rc_c" 0
  [[ -e "$SENTINEL_C" ]] && ok 'C pty local dispatch runs the engine' || bad 'C pty local dispatch runs the engine'
else
  echo 'SKIP C pty local dispatch: script is not installed'
fi

echo "---- seat-hatch: $PASS passed, $FAIL failed"
[[ $FAIL -eq 0 ]]
