#!/usr/bin/env bash
# Behavioral checks for the dispatch-mode terminal_status EXIT trap.
set -uo pipefail

HERE="$(cd "$(dirname "$0")" && pwd)"
ORCH="$HERE/../harness_orchestrator.sh"
STATUS="$HERE/../dispatch_status.py"
PASS=0
FAIL=0

ok(){ echo "  OK: $1"; PASS=$((PASS+1)); }
no(){ echo "  FAIL: $1"; FAIL=$((FAIL+1)); }

test -f "$ORCH" || { echo "FATAL: orchestrator not found at $ORCH"; exit 1; }
test -f "$STATUS" || { echo "FATAL: dispatch_status.py not found at $STATUS"; exit 1; }

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

make_repo() {
    local work="$1"
    mkdir -p "$work"
    git -C "$work" init -q
    git -C "$work" config user.email "trap-test@example.invalid"
    git -C "$work" config user.name "Trap Test"
    printf '[project]\nname = "trap-test"\nversion = "0.0.0"\n' > "$work/pyproject.toml"
    git -C "$work" add pyproject.toml
    git -C "$work" commit -qm "init"
}

write_spec() {
    local spec="$1"
    cat > "$spec" <<'SPEC'
# BUILD_SPEC - terminal trap test

## Phase 1: Forced Failure
engine: claude

Intentionally do nothing useful.

### Validation
```bash
echo "FAILED tests/test_forced.py::test_forced"
false
```
SPEC
}

BIN="$SBX/bin"
mkdir -p "$BIN"
cat > "$BIN/claude" <<'STUB'
#!/usr/bin/env bash
printf 'stub claude invoked with %s args\n' "$#"
exit 0
STUB
chmod +x "$BIN/claude"

# 1. Dispatch-mode failure emits attempt-001/terminal_status.json with a signature.
WORK="$SBX/work"
make_repo "$WORK"
SPEC="$WORK/BUILD_SPEC.md"
write_spec "$SPEC"
RUN_DIR="$SBX/run"
ATTEMPT_DIR="$RUN_DIR/attempt-001"
mkdir -p "$ATTEMPT_DIR"
COMMIT="$(git -C "$WORK" rev-parse HEAD)"
python3 "$STATUS" init \
    --run-dir "$RUN_DIR" \
    --issue REC-TRAP \
    --branch trap-test \
    --worktree "$WORK" \
    --spec "$SPEC" \
    --last-validated-commit "$COMMIT" >/dev/null

OUT="$SBX/dispatch.out"
PATH="$BIN:$PATH" \
DISPATCH_RUN_DIR="$RUN_DIR" \
DISPATCH_ATTEMPT=1 \
bash "$ORCH" --coder claude --dir "$WORK" --log "$ATTEMPT_DIR/build-log.md" --no-codex-spec-review "$SPEC" >"$OUT" 2>&1
RC=$?

[ "$RC" -ne 0 ] && ok "forced validation failure exits nonzero" || no "forced validation failure exited zero"
[ -f "$ATTEMPT_DIR/terminal_status.json" ] \
  && ok "dispatch-mode terminal_status.json written" \
  || no "dispatch-mode terminal_status.json missing"

python3 - "$ATTEMPT_DIR/terminal_status.json" <<'PY'
import json
import sys

with open(sys.argv[1], "r", encoding="utf-8") as handle:
    data = json.load(handle)
assert data["exit_code"] != 0, data
assert data.get("failure_signature"), data
assert data.get("failure_signature") != "null", data
PY
if [ $? -eq 0 ]; then
    ok "terminal_status records nonzero exit and non-null failure_signature"
else
    no "terminal_status missing nonzero exit or failure_signature"
fi

# 2. Foreground dry-run without DISPATCH_RUN_DIR keeps the old no-trap behavior.
FG_WORK="$SBX/foreground"
make_repo "$FG_WORK"
FG_SPEC="$FG_WORK/BUILD_SPEC.md"
write_spec "$FG_SPEC"
FG_OUT="$SBX/foreground.out"
env -u DISPATCH_RUN_DIR -u DISPATCH_ATTEMPT \
    PATH="$BIN:$PATH" \
    bash "$ORCH" --dry-run --coder claude --dir "$FG_WORK" --no-codex-spec-review "$FG_SPEC" >"$FG_OUT" 2>&1
FG_RC=$?

[ "$FG_RC" -eq 0 ] && grep -q "DRY-RUN COMPLETE" "$FG_OUT" \
  && ok "foreground dry-run behavior unchanged" \
  || no "foreground dry-run did not complete normally"

find "$FG_WORK" -name terminal_status.json -print | grep -q . \
  && no "foreground dry-run emitted terminal_status.json" \
  || ok "foreground dry-run does not fire terminal_status trap"

echo "--------"
echo "PASS=$PASS  FAIL=$FAIL"
[ "$FAIL" -eq 0 ]
