#!/usr/bin/env bash
# Behavior regression for reenroll-hosts.sh -- NEW harness (none existed before
# this delivery). Scoped to what this delivery actually changed: the opt-in
# $DC selector wiring (tooling gap register #15 sub-item 2, DOCFIX-166),
# plus a smoke test that --check's read-only reporting is UNCHANGED when $DC
# is unset (backward compatibility). It does not attempt to cover the
# create/poll/tag mutation paths (those require an interactive password
# prompt and a much heavier MAAS fixture set, out of scope for this change).
#
# Fake `maas` (read-only fixture, empty machines list) + real jq.
set -uo pipefail
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SCRIPT="$(cd "$HERE/../../scripts" && pwd)/reenroll-hosts.sh"
BIN="$HERE/fakebin"; FIX="$HERE/fix"
chmod +x "$BIN"/* 2>/dev/null || true   # GitHub Desktop lands files mode 100644
command -v jq >/dev/null || { echo "FAIL: jq required"; exit 1; }
rc_all=0; OUT="$(mktemp)"

# run: --check mode, nothing enrolled (fake maas returns "[]" for machines read).
# < /dev/null so a bug that ever reached the interactive password prompt fails
# loudly (EOF) instead of hanging the harness.
run() {  # <want_exit> <label> <dc_value>
  local want="$1" label="$2" dcval="$3"
  DC="$dcval" PATH="$BIN:$PATH" FIX_MACHINES="$FIX/machines_empty.json" \
    bash "$SCRIPT" --check </dev/null >"$OUT" 2>&1
  local rc=$?
  if [ "$rc" -ne "$want" ]; then
    printf '  [XX] %-52s exit %s (want %s)\n' "$label" "$rc" "$want"; sed 's/^/        /' "$OUT"; rc_all=1; return
  fi
  printf '  [ok] %-52s exit %s\n' "$label" "$rc"
}

# run_dc: no fixtures needed -- $DC values expected to fail loud at the
# selector layer, BEFORE the script ever calls need_jq/report()/MAAS.
run_dc() {  # <want_exit> <label> <dc_value>
  local want="$1" label="$2" dcval="$3"
  DC="$dcval" bash "$SCRIPT" --check </dev/null >"$OUT" 2>&1
  local rc=$?
  if [ "$rc" -ne "$want" ]; then
    printf '  [XX] %-52s exit %s (want %s)\n' "$label" "$rc" "$want"; sed 's/^/        /' "$OUT"; rc_all=1; return
  fi
  printf '  [ok] %-52s exit %s\n' "$label" "$rc"
}
has()    { grep -qE "$1" "$OUT" || { printf '       MISS expected /%s/\n' "$1"; rc_all=1; }; }
absent() { grep -qE "$1" "$OUT" && { printf '       LEAK forbidden /%s/\n' "$1"; rc_all=1; } || true; }

echo "=== reenroll-hosts.sh -- \$DC selector wiring (fake maas + real jq) ==="

run 0 "unset \$DC (backward compat): --check unaffected" ""
has 'NOT-ENROLLED'
has 'read-only check mode; no changes made'

run 0 "DC=vr0-dc0 explicit: identical --check output" vr0-dc0
has 'NOT-ENROLLED'
has 'read-only check mode; no changes made'

run_dc 1 "DC=vr1-dc0: REFUSED (D-133 guard -- VR0 flow, VR1 arms populated 2026-07-23)" vr1-dc0
has 'VR1 re-enrollment is PXE re-enlist'
absent 'Current host status'                                    # must exit before report() ever runs

run_dc 1 "DC=vr1-dc1: REFUSED (D-133 guard -- VR0 flow, VR1 arms populated 2026-07-23)" vr1-dc1
has 'VR1 re-enrollment is PXE re-enlist'
absent 'Current host status'

# D-119 REGRESSION GUARD: the bare dcN tokens are RETIRED. 'dc0' used to mean
# VR0's LIVE cloud here but VR1's FIRST DC in the NetBox importer -- one string,
# two clouds. Accepting it silently is how the off-by-one comes back.
for _bare in dc0 dc1 dc2; do
  run_dc 1 "DC=$_bare: RETIRED bare selector is REJECTED (D-119)" "$_bare"
  has 'RETIRED'
done

run_dc 1 "DC=bogus: unknown token fails loud" bogus
has "unknown DC 'bogus'"

echo
[ "$rc_all" -eq 0 ] && echo "ALL PASS" || echo "SOME FAILED"
rm -f "$OUT"; exit "$rc_all"
