#!/usr/bin/env bash
# tests/dc-rack-net/run-tests.sh -- guard for scripts/dc-rack-net.sh (D-131
# sub-1 standing per-DC pattern + D-128 item 20 rack-legs persistence).
# Static: syntax, the dc0 identity values (measured 2026-07-21 -- changing one
# silently breaks node DNS or rack addressing), stable-identity keying (libvirt
# net names, never virbrN literals), forwarder confinement (no-resolv, single
# upstream), and the MEASURED-tag discipline on site rows.
# Exit: 0 all pass | 1 any case failed. ASCII + LF.
set -uo pipefail
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SCRIPT="$(cd "$HERE/../.." && pwd)/scripts/dc-rack-net.sh"
PASS=0; FAIL=0
ok(){ echo "  PASS  $1"; PASS=$((PASS+1)); }
no(){ echo "  FAIL  $1"; FAIL=$((FAIL+1)); }

[ -f "$SCRIPT" ] && ok "T1 script present" || { no "T1 script present"; echo; echo "dc-rack-net: $PASS passed, $((FAIL)) failed"; exit 1; }
bash -n "$SCRIPT" 2>/dev/null && ok "T2 bash -n clean" || no "T2 bash -n clean"

# T3-T5: dc0 identity values exactly as measured 2026-07-21
grep -q 'vr1-dc0-metal-admin=10.12.8.2/22' "$SCRIPT" \
  && ok "T3 dc0 rack MAAS/DHCP leg 10.12.8.2/22 on metal-admin" \
  || no "T3 dc0 rack MAAS/DHCP leg 10.12.8.2/22 on metal-admin"
grep -q 'vr1-dc0-metal-admin=10.12.8.3/22' "$SCRIPT" \
  && grep -q 'DNS_LISTEN="10.12.8.3"' "$SCRIPT" \
  && ok "T4 dc0 forwarder alias + listen 10.12.8.3" \
  || no "T4 dc0 forwarder alias + listen 10.12.8.3"
grep -q 'vr1-dc0-provider-public=10.12.4.2/22' "$SCRIPT" \
  && grep -q 'DNS_UPSTREAM="10.10.0.20"' "$SCRIPT" \
  && ok "T5 dc0 edge-LAN leg + region upstream" \
  || no "T5 dc0 edge-LAN leg + region upstream"

# T6: stable-identity keying -- bridges resolved from libvirt net names; NO
# virbrN literal anywhere (the auto-assigned name is a drifting ID)
grep -q 'net-dumpxml' "$SCRIPT" && ! grep -q 'virbr[0-9]' "$SCRIPT" \
  && ok "T6 bridges resolved from net names; no virbrN literal" \
  || no "T6 bridges resolved from net names; no virbrN literal"

# T7-T9: forwarder confinement (the D-131 shape: closed resolver, one upstream,
# OUTPUT-only traffic -- SEC-010 depends on it staying a forwarder, not a router)
grep -q 'no-resolv' "$SCRIPT" && ok "T7 dnsmasq no-resolv" || no "T7 dnsmasq no-resolv"
grep -q 'bind-interfaces' "$SCRIPT" && ok "T8 dnsmasq bind-interfaces (alias only)" || no "T8 dnsmasq bind-interfaces (alias only)"
grep -q 'server=\${DNS_UPSTREAM}' "$SCRIPT" \
  && ok "T9 single templated upstream (region BIND)" \
  || no "T9 single templated upstream (region BIND)"

# T10: MEASURED-tag discipline -- the dc0 site block carries MEASURED citations
SITE_BLOCK="$(awk '/^  dc0\)/{f=1} f{print} f&&/;;/{exit}' "$SCRIPT")"
grep -q 'MEASURED' <<<"$SITE_BLOCK" \
  && ok "T10 dc0 site rows cite MEASURED provenance" \
  || no "T10 dc0 site rows cite MEASURED provenance"

# T11: unknown site refuses (hard rule 2 -- no inferred rows)
OUT="$(bash "$SCRIPT" check nosuchsite 2>&1)"; RC=$?
[ "$RC" -eq 2 ] && grep -q 'MEASURED' <<<"$OUT" \
  && ok "T11 unknown site exits 2 and demands measured rows" \
  || no "T11 unknown site exits 2 and demands measured rows (rc=$RC)"

# T12: bad mode refuses
bash "$SCRIPT" frobnicate dc0 >/dev/null 2>&1; RC=$?
[ "$RC" -eq 2 ] && ok "T12 bad mode exits 2" || no "T12 bad mode exits 2 (rc=$RC)"

# T13: units are ordered -- dns unit Requires + After the legs unit (the alias
# must exist before dnsmasq binds it)
grep -q 'Requires=\${SITE}-rack-legs.service' "$SCRIPT" \
  && grep -q 'After=\${SITE}-rack-legs.service' "$SCRIPT" \
  && ok "T13 dns unit Requires/After legs unit" \
  || no "T13 dns unit Requires/After legs unit"

# T14: check path never mutates -- no ip/systemctl mutation verbs inside do_check
CHECK_BLOCK="$(awk '/^do_check\(\)/{f=1} f{print} f&&/^}/{exit}' "$SCRIPT")"
grep -qE 'addr (add|replace|del)|systemctl (enable|restart|start|disable)|daemon-reload|> *"?\$' <<<"$CHECK_BLOCK" \
  && no "T14 do_check is read-only" \
  || ok "T14 do_check is read-only"

# T15-T17: dc1 identity values (measured/apex-committed 2026-07-22..23 --
# provider-public leg measured live on the bridge, metal-admin leg = the
# apex-committed rack IP, forwarder = D-120 static; changing one silently
# breaks dc1 node DNS or rack addressing)
grep -q 'vr1-dc1-metal-admin=10.12.68.2/22' "$SCRIPT" \
  && ok "T15 dc1 rack MAAS/DHCP leg 10.12.68.2/22 on metal-admin" \
  || no "T15 dc1 rack MAAS/DHCP leg 10.12.68.2/22 on metal-admin"
grep -q 'vr1-dc1-metal-admin=10.12.68.3/22' "$SCRIPT" \
  && grep -q 'DNS_LISTEN="10.12.68.3"' "$SCRIPT" \
  && ok "T16 dc1 forwarder alias + listen 10.12.68.3" \
  || no "T16 dc1 forwarder alias + listen 10.12.68.3"
grep -q 'vr1-dc1-provider-public=10.12.64.2/22' "$SCRIPT" \
  && ok "T17 dc1 edge-LAN leg 10.12.64.2/22 on provider-public" \
  || no "T17 dc1 edge-LAN leg 10.12.64.2/22 on provider-public"

# T18: dc1 site block carries MEASURED citations (hard rule 2)
DC1_BLOCK="$(awk '/^  dc1\)/{f=1} f{print} f&&/;;/{exit}' "$SCRIPT")"
grep -q 'MEASURED' <<<"$DC1_BLOCK" \
  && ok "T18 dc1 site rows cite MEASURED provenance" \
  || no "T18 dc1 site rows cite MEASURED provenance"

echo; echo "dc-rack-net: $PASS passed, $FAIL failed"
[ "$FAIL" -eq 0 ]
