#!/usr/bin/env bash
# tests/dc-edge-wan-import/run-tests.sh
#
# Harness for netbox/dc-edge-wan-import.py. OFFLINE -- touches no NetBox.
#
# Two layers, both required (mirrors d120-compose-bands + dc-dc-prefixes-import):
#   1. STATIC greps that PIN the D-115 edge values + the guards every sandbox-loop
#      writer must have (dry-by-default, upstream-write gated IN CODE, whole-plan
#      preflight). A changed constant that a behavioral test would ALSO change is
#      caught here.
#   2. test_logic.py drives the REAL main()/preflight against an in-memory fake NB
#      (injected at the get_nb() seam) -- half-write guard, scope-not-swapped,
#      idempotent-skip, dry-run-writes-nothing. In-process on purpose: no port /
#      readiness / cleanup flakiness to redden the shared gauntlet.
# ASCII + LF.
set -uo pipefail
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
S="$(cd "$HERE/../../netbox" && pwd)/dc-edge-wan-import.py"
pass=0; fail=0
ok()  { pass=$((pass+1)); }
bad() { fail=$((fail+1)); echo "  FAIL: $1"; }

command -v python3 >/dev/null 2>&1 || { echo "FAIL: python3 required"; exit 1; }

python3 -c "import ast;ast.parse(open('$S').read())" 2>/dev/null && ok || bad "does not parse"
python3 "$S" --help >/dev/null 2>&1 && ok || bad "--help -> 0"

# no env -> must fail loud, not guess a target
NETBOX_URL= NETBOX_TOKEN= python3 "$S" >/dev/null 2>&1; [ $? -ne 0 ] && ok || bad "missing NETBOX_URL/TOKEN must fail"

# DRY BY DEFAULT
grep -q '"--commit", action="store_true"' "$S" && ok || bad "no --commit flag -- must be dry by default"
grep -q 'DRY RUN -- nothing will be written' "$S" && ok || bad "does not announce its dry run"

# UPSTREAM WRITE GATED IN CODE (not by discipline)
grep -q 'yes-write-upstream' "$S" && ok || bad "lost the --yes-write-upstream gate"
grep -q 'SANDBOX_HOSTS' "$S" && ok || bad "lost the SANDBOX_HOSTS gate"
out="$(NETBOX_URL=https://netbox.baldurkeep.com NETBOX_TOKEN=x python3 "$S" --commit 2>&1)"
printf '%s' "$out" | grep -q "REFUSING to --commit" && ok \
  || bad "did NOT refuse a --commit to a non-sandbox host (it would have written to production)"

# WAF: UA-aware or every upstream call 403s (looks like auth failure)
grep -q 'User-Agent' "$S" && grep -q 'curl/8.5.0' "$S" && ok || bad "lost the WAF-safe User-Agent"

# WHOLE-PLAN PREFLIGHT -- validate role/container/placement/site BEFORE any create
grep -q "outside the Edge container" "$S" && ok || bad "lost the in-container preflight"
grep -q "container .* absent" "$S" && ok || bad "lost the container-exists preflight"
grep -q "role '.*' absent" "$S" && ok || bad "lost the role-exists preflight"
grep -q "site '.*' absent" "$S" && ok || bad "lost the site-resolves preflight"

# THE D-115 EDGE VALUES -- the two DC /24s, their role, and their SITE scope.
grep -qF '("172.30.2.0/24", "vr1-dc0"' "$S" && ok || bad "172.30.2.0/24 -> vr1-dc0 binding is GONE / changed"
grep -qF '("172.30.3.0/24", "vr1-dc1"' "$S" && ok || bad "172.30.3.0/24 -> vr1-dc1 binding is GONE / changed"
grep -qF 'ROLE_SLUG = "edge"' "$S" && ok || bad "edge role slug changed"
grep -qF 'CONTAINER = "172.30.0.0/16"' "$S" && ok || bad "Edge container is not 172.30.0.0/16"
grep -q '"scope_type": "dcim.site"' "$S" && ok || bad "the /24s are not dcim.site-scoped (must match office1-wan)"

# This tool must NOT create the role/container/sites -- they are preconditions.
grep -q 'ipam/roles".*payload\|create("ipam/roles"\|create("dcim/sites"' "$S" \
  && bad "this tool CREATES a role/site -- those are preconditions, it must only create the /24s" || ok

# ---- behavioral layer: drive the real main() against the injected fake NB ----
echo "  -- behavioral (test_logic.py) --"
tl_out="$(python3 "$HERE/test_logic.py" 2>&1)"; tl_rc=$?
printf '%s\n' "$tl_out" | grep -E '^(FAIL|PASS: |test_logic:)' | sed 's/^/    /'
tl_n="$(printf '%s\n' "$tl_out" | sed -n 's/^test_logic: ALL PASS (\([0-9]*\) checks)$/\1/p')"
if [ "$tl_rc" -eq 0 ] && [ -n "$tl_n" ]; then
  pass=$((pass + tl_n))
else
  bad "test_logic.py behavioral suite FAILED (rc=$tl_rc)"
fi

echo
total=$((pass+fail))
if [ "$fail" -eq 0 ]; then echo "dc-edge-wan-import: $pass/$total PASS"; exit 0; fi
echo "dc-edge-wan-import: $fail/$total FAIL"; exit 1
