#!§A1H bash
set -euo pipefail

# The fixture repo below carries no modules/harness, so a reachable buildbox receives a
# tree that cannot run gates.sh. These assert gate0 running locally.
export GATE0_REMOTE=0

# Attribution contract: a red check is only the task's fault if it reproduces.
# gate0 re-runs the failing check alone with runner parallelism pinned to one.
#   green on re-run          -> contention, gate passes
#   same failure set         -> real red, FAILCLASS=check-failed
#   different failure set    -> nondeterministic, FAILCLASS=flaky-check
#   no per-test failures     -> build/lint red, no re-run at all

ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
GATES="$ROOT_DIR/lib/gates.sh"

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

fail=0

# $1 case  $2 expected rc  $3 check body keyed on run count  $4 output substring  $5 times the check must run
run_case() {
  local name=$1 want_rc=$2 script=$3 want_pattern=${4:-} want_runs=${5:-}
  local repo="$tmp/$name" rc=0 out
  mkdir -p "$repo"
  git -C "$repo" init -q
  git -C "$repo" config user.email t@example.com
  git -C "$repo" config user.name t
  printf '%s\n' "$script" >"$repo/run-check.sh"
  chmod +x "$repo/run-check.sh"
  printf 'test:\n\t@./run-check.sh\n' >"$repo/Makefile"
  git -C "$repo" add -A
  git -C "$repo" commit -qm base

  out=$(cd "$repo" && RUNPLAN_GATE_STALL_MS=0 bash "$GATES" gate0 strict "$repo" "$repo" attribution 2>&1) || rc=$?

  if [[ "$rc" != "$want_rc" ]]; then
    echo "FAIL $name: rc=$rc want=$want_rc"
    printf '%s\n' "$out" | tail -15
    fail=1
    return
  fi
  if [[ -n "$want_pattern" ]] && ! printf '%s\n' "$out" | grep -Fq "$want_pattern"; then
    echo "FAIL $name: output missing '$want_pattern'"
    printf '%s\n' "$out" | tail -15
    fail=1
    return
  fi
  local runs
  runs=$(cat "$repo/.runs" 2>/dev/null || echo 0)
  if [[ -n "$want_runs" && "$runs" != "$want_runs" ]]; then
    echo "FAIL $name: check ran ${runs}x want ${want_runs}x"
    fail=1
    return
  fi
  echo "PASS $name (rc=$rc, runs=$runs)"
}

counter_prelude='#!/usr/bin/env bash
n=$(cat .runs 2>/dev/null || echo 0); n=$((n+1)); echo "$n" >.runs'

# Red once, green when re-run alone: the first red was contention.
run_case contention-recovers 0 "$counter_prelude"'
if [[ $n -eq 1 ]]; then echo "not ok 1 - alpha times out"; exit 1; fi
echo "ok 1 - alpha"; exit 0' \
  "isolated re-run green" 2

# Red every time with the same failure: a genuine red the fixer should see.
run_case real-red-stays-red 1 "$counter_prelude"'
echo "not ok 1 - alpha is broken"; exit 1' \
  "FAILCLASS=check-failed" 2

# Red every time but a different test each run: no diff can repair this.
run_case nondeterministic-flagged 1 "$counter_prelude"'
if [[ $n -eq 1 ]]; then echo "not ok 1 - alpha"; else echo "not ok 2 - beta"; fi
exit 1' \
  "FAILCLASS=flaky-check" 2

# A compile error reports no per-test failures, so attribution is unambiguous
# and the check must fail closed without paying for a second run.
run_case build-red-no-retry 1 "$counter_prelude"'
echo "error TS2345: argument not assignable"; exit 1' \
  "FAILCLASS=check-failed" 1

if [[ $fail -eq 0 ]]; then
  echo "gate-attribution: ok"
else
  echo "gate-attribution: FAILED"
fi
exit "$fail"
