#!/bin/sh
# Unit tests for CI helpers (pure/deterministic; no real bus or push needed).
# Run: sh tests/ci-gates.sh   (exit 0 = pass).
. "$(dirname "$0")/../ci/lib/spt-bus.sh"
fail=0

# resolve_spt_send: explicit override wins. Use a REAL executable (sh) — MSYS does not honour
# `chmod +x` on an arbitrary temp file as `-x`, so synthesise nothing.
# [unit->REQ-CI-OWL-DISCOVERY]
t_resolve_spt_send() {
realexe=$(command -v sh)
got=$(SPTC_CI_BUS="$realexe" resolve_spt_send)
[ "$got" = "$realexe" ] && echo "ok   override resolves" || { echo "FAIL override: got [$got]"; fail=1; }

# resolve_spt_send: a non-executable override is ignored (no false positive).
bad=$(mktemp)  # plain file, not executable
got=$(SPTC_CI_BUS="$bad" resolve_spt_send 2>/dev/null)
[ "$got" != "$bad" ] && echo "ok   non-exec override rejected" || { echo "FAIL non-exec accepted"; fail=1; }
rm -f "$bad"
}
t_resolve_spt_send

# run-gates.sh: valid shell + carries the load-bearing gates. [unit->REQ-CI-GATES]
t_run_gates() {
g="$(dirname "$0")/../ci/run-gates.sh"
sh -n "$g" && echo "ok   run-gates syntax" || { echo "FAIL run-gates syntax"; fail=1; }
grep -q 'traceable-reqs check' "$g" && echo "ok   gate: traceable-reqs" || { echo "FAIL missing traceable gate"; fail=1; }
grep -q 'sh -n' "$g" && echo "ok   gate: shell-syntax" || { echo "FAIL missing syntax gate"; fail=1; }
# The read-only ints must stay WIRED INTO the gate, by path. Building a crate is not running its int:
# translate-proof-int sat red for ~3 weeks after the stub migration because the gate built the
# idle-translate crate and never executed the int. [unit->REQ-CI-GATES]
for i in ci/idle-translate/translate-proof-int.sh ci/digest/digest-proof-int.sh; do
  grep -q "$i" "$g" && echo "ok   gate runs read-only int: $i" ||
    { echo "FAIL run-gates no longer runs $i — a requirement whose int the gate never runs is not covered"; fail=1; }
done
}
t_run_gates

# ── sptc_flag_supported separates "no flag" from "no answer".
# [unit->REQ-HAZARD-VERSION-GATE-FAIL-CLOSED]
# The three outcomes must stay DISTINCT: collapsing rc 2 (probe failed) into rc 1 (flag absent) is
# the whole defect — a refusing command and a feature that predates a flag produce the same empty
# grep, and only the exit code plus the `usage` positive control tell them apart.
. "$(dirname "$0")/../ci/lib/spt-probe.sh"
pstub=$(mktemp -d)
cat > "$pstub/withflag" <<'STUBEOF'
#!/bin/sh
echo "Usage: withflag [OPTIONS] --dir <D>"
STUBEOF
cat > "$pstub/noflag" <<'STUBEOF'
#!/bin/sh
echo "Usage: noflag [OPTIONS]"
STUBEOF
cat > "$pstub/refuses" <<'STUBEOF'
#!/bin/sh
echo "error: unrecognized subcommand" >&2; exit 2
STUBEOF
chmod +x "$pstub/withflag" "$pstub/noflag" "$pstub/refuses"

# POSITIVE CONTROL on the stubs, for the same reason the probe has one.
if "$pstub/withflag" --help >/dev/null 2>&1; then
  sptc_flag_supported '--dir' "$pstub/withflag"; [ $? -eq 0 ] &&
    echo "ok   probe: answered + flag present => 0" || { echo "FAIL probe: expected rc 0"; fail=1; }
  sptc_flag_supported '--dir' "$pstub/noflag";   [ $? -eq 1 ] &&
    echo "ok   probe: answered + flag absent => 1 (honest gap)" || { echo "FAIL probe: expected rc 1"; fail=1; }
  sptc_flag_supported '--dir' "$pstub/refuses";  [ $? -eq 2 ] &&
    echo "ok   probe: no answer => 2, NOT confused with 'flag absent'" || { echo "FAIL probe: expected rc 2"; fail=1; }
  # A command that exits 0 but prints no usage body is also an unusable answer, not a capability gap.
  sptc_flag_supported '--dir' true; [ $? -eq 2 ] &&
    echo "ok   probe: empty body => 2 (no positive control, no verdict)" || { echo "FAIL probe: empty body should be rc 2"; fail=1; }
else
  echo "FAIL probe stubs not executable — assertions would pass vacuously"; fail=1
fi
rm -rf "$pstub"

# ── The multi-subnet int's bringup gate FAILS CLOSED.
# Driven with a stubbed `spt` rather than asserted by grep: the bug being pinned was a predicate that
# READ green while measuring nothing, so a static shape-check would reproduce the very defect.
INT="$(dirname "$0")/../ci/subnet/multi-subnet-bringup-int.sh"
sh -n "$INT" && echo "ok   multi-subnet int syntax" || { echo "FAIL multi-subnet int syntax"; fail=1; }

stub=$(mktemp -d)
# spt >= 0.54.0: `endpoint run` is retired and refuses; the lifecycle verbs are present.
cat > "$stub/spt" <<'STUBEOF'
#!/bin/sh
case "$1 $2" in
  "endpoint run")    echo "error: unrecognized subcommand 'run'" >&2; exit 2 ;;
  "endpoint create") exit 0 ;;
esac
exit 0
STUBEOF
chmod +x "$stub/spt"

# POSITIVE CONTROL on the instrument itself. If the stub cannot execute (MSYS does not always honour
# chmod on a synthesised file), every assertion below would pass for the wrong reason — so an
# unusable stub is a FAILURE of this test, never a quiet pass.
# [unit->REQ-HAZARD-VERSION-GATE-FAIL-CLOSED]
if PATH="$stub:$PATH" spt endpoint create --help >/dev/null 2>&1 &&
   ! PATH="$stub:$PATH" spt endpoint run --help >/dev/null 2>&1; then
  out=$(PATH="$stub:$PATH" sh "$INT" 2>&1); rc=$?
  [ "$rc" -ne 0 ] &&
    echo "ok   retired 'endpoint run' => int fails closed" ||
    { echo "FAIL 0.54.0 shape: int exited 0 (green-by-skip on the version it must test)"; fail=1; }
  # `^SKIP` — the ANNOUNCEMENT form the int emits (`echo "SKIP: ..."`). A bare `SKIP` match also hits
  # the refusal's own "Refusing to SKIP:" wording and fails the fix for quoting the thing it prevents.
  if printf '%s' "$out" | grep -q '^SKIP'; then
    echo "FAIL 0.54.0 shape: int announced SKIP for a MOVED feature"; fail=1
  else
    echo "ok   retired 'endpoint run' => no SKIP claimed"
  fi
else
  echo "FAIL stub spt is not executable — the gate assertions would pass vacuously"; fail=1
fi

# BLAST RADIUS: a genuinely pre-v0.14.0 build must still SKIP. Failing closed must not mean
# failing always — a gate that never skips is as useless as one that always does.
cat > "$stub/spt" <<'STUBEOF'
#!/bin/sh
if [ "$1 $2" = "endpoint run" ]; then echo "Usage: spt endpoint run [OPTIONS] --adapter <A>"; exit 0; fi
exit 0
STUBEOF
chmod +x "$stub/spt"
out=$(PATH="$stub:$PATH" sh "$INT" 2>&1); rc=$?
{ [ "$rc" -eq 0 ] && printf '%s' "$out" | grep -q 'SKIP'; } &&
  echo "ok   pre-v0.14.0 'endpoint run' => still skips honestly" ||
  { echo "FAIL pre-v0.14.0: expected SKIP/exit 0, got rc=$rc [$out]"; fail=1; }
rm -rf "$stub"

[ "$fail" -eq 0 ] && { echo "CI-HELPERS OK"; exit 0; } || { echo "CI-HELPERS FAIL"; exit 1; }
