#!/usr/bin/env bash
# tests/maas-profile-assert/run-tests.sh -- unit tests for
# scripts/maas-profile-assert.sh (the wrong-REGION guard, 2026-07-30).
#
# Asserts, with a STUB `maas` on PATH so no live region is touched:
#  - a matching rack-controller set exits 0; a DIFFERENT region exits 1.
#  - expected-set ORDER does not matter (the script sorts both sides).
#  - EVERY refusal direction exits 2 rather than passing: no CLI, unknown
#    profile (maas rc!=0), unparseable JSON, EMPTY rack list, nameless entries.
#  - missing arguments exit 2.
#
# THE EMPTY-LIST CASE IS THE POINT OF THE HARNESS. A region that answers but
# reports no rack controllers must REFUSE, not pass -- otherwise the guard
# green-lights a `machine delete` against an unidentified region, which is the
# exact "a checker that cannot fail is not a gate" class this repo keeps
# finding.
#
# MUTATION PASS, 2026-07-30 -- each assertion was verified to FAIL when its
# branch is removed. Recorded because the pass FOUND ONE: mutation C (accept
# nameless rack entries) left the suite fully GREEN, because a nameless entry
# fell through to the generic empty-ACTUAL guard and refused for a different
# reason. That assertion was decoration until it was made branch-specific by
# asserting the refusal's own message. Mutations A (comparison always true)
# and B (empty list accepted) each killed 4 tests.
set -uo pipefail
SD="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SCRIPT="$SD/../../scripts/maas-profile-assert.sh"
P=0; F=0
ok(){ echo "PASS: $1"; P=$((P+1)); }
no(){ echo "FAIL: $1"; F=$((F+1)); }
chk(){ [ "$2" = "$3" ] && ok "$1" || no "$1 (got '$2' want '$3')"; }

TMP="$(mktemp -d)"
trap 'rm -rf "$TMP"' EXIT
mkdir -p "$TMP/bin"

# The stub reads $STUB_MODE and emits a canned rack-controllers payload.
cat > "$TMP/bin/maas" <<'STUB'
#!/usr/bin/env bash
case "${STUB_MODE:-}" in
  office1)   echo '[{"hostname":"voffice1"},{"hostname":"vvr1-dc0"},{"hostname":"vvr1-dc1"}]' ;;
  dc0)       echo '[{"hostname":"hot-kid"}]' ;;
  empty)     echo '[]' ;;
  nameless)  echo '[{"system_id":"abc123"}]' ;;
  garbage)   echo 'not json at all' ;;
  notalist)  echo '{"error":"nope"}' ;;
  fail)      echo 'Profile "bogus" is not known' >&2; exit 2 ;;
  *)         echo '[]' ;;
esac
STUB
chmod +x "$TMP/bin/maas"

run(){ # run <stub-mode> <args...> -> sets RC, OUT
  local mode="$1"; shift
  OUT="$(STUB_MODE="$mode" PATH="$TMP/bin:$PATH" bash "$SCRIPT" "$@" 2>&1)"
  RC=$?
}

# --- usage ---
run dc0;                       chk "no args -> 2"            "$RC" 2
run dc0 vr1-dc0-region;        chk "one arg -> 2"            "$RC" 2

# --- the happy paths ---
run dc0 vr1-dc0-region hot-kid
chk "dc0 region matches hot-kid -> 0" "$RC" 0
case "$OUT" in *"as expected"*) ok "match prints an OK line" ;; *) no "match prints an OK line (got '$OUT')" ;; esac

run office1 admin voffice1,vvr1-dc0,vvr1-dc1
chk "office1 region matches its three racks -> 0" "$RC" 0

# order of the EXPECTED set must not matter
run office1 admin vvr1-dc1,voffice1,vvr1-dc0
chk "expected-set order is irrelevant -> 0" "$RC" 0

# --- the wrong-region direction (exit 1) ---
run office1 admin hot-kid
chk "office1 region asserted as dc0 -> 1" "$RC" 1
case "$OUT" in *"WRONG region"*) ok "mismatch names the failure" ;; *) no "mismatch names the failure (got '$OUT')" ;; esac

run dc0 vr1-dc0-region voffice1,vvr1-dc0,vvr1-dc1
chk "dc0 region asserted as office1 -> 1" "$RC" 1

# a SUBSET must not pass -- office1 has three racks, not one of them
run office1 admin voffice1
chk "subset of the rack set -> 1" "$RC" 1

# --- refusals: every one of these must be 2, never 0 ---
run empty vr1-dc0-region hot-kid
chk "EMPTY rack list REFUSES (does not pass) -> 2" "$RC" 2
case "$OUT" in *EMPTY*) ok "empty-list refusal says why" ;; *) no "empty-list refusal says why (got '$OUT')" ;; esac

run nameless vr1-dc0-region hot-kid
chk "nameless rack entries REFUSE -> 2" "$RC" 2
# Branch-specific: the first version of this test passed for the WRONG REASON --
# a nameless entry fell through to the generic empty-ACTUAL guard, so deleting
# the nameless branch left the suite green (mutation C, 2026-07-30). Asserting
# the branch's OWN message is what makes the assertion able to fail.
case "$OUT" in *NAMELESS*) ok "nameless refusal fires its OWN branch" ;; *) no "nameless refusal fires its OWN branch (got '$OUT')" ;; esac

run garbage vr1-dc0-region hot-kid
chk "unparseable JSON REFUSES -> 2" "$RC" 2

run notalist vr1-dc0-region hot-kid
chk "non-list JSON REFUSES -> 2" "$RC" 2

run fail bogus-profile hot-kid
chk "unknown profile (maas rc!=0) REFUSES -> 2" "$RC" 2

# an empty EXPECTED set must never be satisfiable by an empty actual set
run empty vr1-dc0-region ,,,
chk "empty expected + empty actual still REFUSES -> 2" "$RC" 2

# --- no CLI at all ---
OUT="$(PATH="$TMP/emptybin:/usr/bin:/bin" bash "$SCRIPT" vr1-dc0-region hot-kid 2>&1)"; RC=$?
chk "absent maas CLI REFUSES -> 2" "$RC" 2

# --- the script must never leak the payload body on a CLI error ---
run fail bogus-profile hot-kid
case "$OUT" in *"is not known"*) no "CLI error body is echoed verbatim (leak risk)" ;; *) ok "CLI error body is not echoed verbatim" ;; esac

echo
echo "maas-profile-assert: $P passed, $F failed"
[ "$F" -eq 0 ] || exit 1
