#!/usr/bin/env bash
# tests/clientdocs-skill/run-tests.sh -- content gate for the tenant AI-assistant
# skill package (clientdocs/tenant-skill/). Read-only; mutates nothing.
#
# Gates, in order:
#   T1  layout: SKILL.md + references/ exist
#   T2  frontmatter present and parses (name: omega-cloud-tenant, description)
#   T3  zero internal-term leakage (identifiers, tooling names, component code
#       names, internal hosts/CIDRs) across every skill file
#   T4  placeholder inventory is EXACTLY the documented set (clientdocs/README.md)
#   T5  routing: every references/*.md is reachable from SKILL.md, and every
#       references/ path mentioned anywhere in the skill exists
#   T6  ASCII + LF (belt and braces; repo lint L1 also covers this)
#   T7  expected-refusal table present in troubleshooting.md
#   T8  starter-script references: every *.sh named in the skill/guide exists
#       in clientdocs/scripts/, and every starter script parses (bash -n)
# Exit: 0 all pass | 1 any case failed.  ASCII + LF.
set -uo pipefail
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO="$(cd "$HERE/../.." && pwd)"
SKILL="$REPO/clientdocs/tenant-skill"
PASS=0; FAIL=0
ok()  { echo "  PASS  $1"; PASS=$((PASS+1)); }
bad() { echo "  FAIL  $1"; shift; for l in "$@"; do echo "        $l"; done; FAIL=$((FAIL+1)); }

# ---- T1 layout ----
if [[ -f "$SKILL/SKILL.md" && -d "$SKILL/references" ]]; then
  ok "T1 layout: SKILL.md + references/ present"
else
  bad "T1 layout missing (SKILL.md or references/)"; echo; echo "RESULT: PASS=$PASS FAIL=$FAIL"; exit 1
fi
mapfile -t FILES < <(find "$SKILL" -name '*.md' | sort)

# ---- T2 frontmatter ----
FM_OUT="$(python3 - "$SKILL/SKILL.md" <<'PY' 2>&1
import sys
t = open(sys.argv[1], encoding="ascii").read()
if not t.startswith("---\n"):
    raise SystemExit("no opening frontmatter fence")
end = t.find("\n---\n", 4)
if end < 0:
    raise SystemExit("no closing frontmatter fence")
fm = t[4:end]
fields = {}
for ln in fm.splitlines():
    if ":" in ln:
        k, v = ln.split(":", 1)
        fields[k.strip()] = v.strip().strip('"')
if fields.get("name") != "omega-cloud-tenant":
    raise SystemExit("name is %r, want omega-cloud-tenant" % fields.get("name"))
if len(fields.get("description", "")) < 80:
    raise SystemExit("description missing or too short to trigger on")
print("frontmatter ok")
PY
)"
if [[ "$FM_OUT" == "frontmatter ok" ]]; then
  ok "T2 frontmatter parses (name=omega-cloud-tenant, description present)"
else
  bad "T2 frontmatter" "$FM_OUT"
fi

# ---- T3 internal-term leakage: must return NOTHING ----
# Internal identifiers, operator tooling, component code names, internal
# hosts/CIDRs. No sanctioned exceptions inside the skill package. The
# client-facing usage page for the skill is scanned too.
LEAK_RX='D-0[0-9]{2}|DOCFIX|BUNDLEFIX|juju|charm|maas|vault|ceph|ovn[^a-z]|magnum|octavia|barbican|keystone|horizon|glance|cinder|neutron|nova[^a-z]|amphora|capi|caracal|runbook|10\.12\.|baldurkeep|vopenstack|neumatrix|jumphost'
LEAK_FILES=("${FILES[@]}")
[[ -f "$REPO/clientdocs/ai-assistant-guide.md" ]] && LEAK_FILES+=("$REPO/clientdocs/ai-assistant-guide.md")
[[ -f "$REPO/clientdocs/jenkins-kubernetes-guide.md" ]] && LEAK_FILES+=("$REPO/clientdocs/jenkins-kubernetes-guide.md")
for s in "$REPO"/clientdocs/scripts/*.sh; do [[ -f "$s" ]] && LEAK_FILES+=("$s"); done
LEAKS="$(grep -rniE "$LEAK_RX" "${LEAK_FILES[@]}" 2>/dev/null)"
if [[ -z "$LEAKS" ]]; then
  ok "T3 zero internal-term leakage"
else
  bad "T3 internal-term LEAK(s):" "$(echo "$LEAKS" | head -5)"
fi

# ---- T4 placeholder inventory ----
# Documented set (clientdocs/README.md). {{THIS}} is the TEMPLATE NOTE
# meta-token shared with the other clientdocs templates, not a placeholder.
WANT="ACCOUNT_CONTACT AUTH_URL DASHBOARD_URL REGION TENANT_SHORT_NAME"
GOT="$(grep -ohE '\{\{[A-Za-z0-9_]+\}\}' "${FILES[@]}" | tr -d '{}' | grep -v '^THIS$' | sort -u | tr '\n' ' ' | sed 's/ $//')"
if [[ "$GOT" == "$WANT" ]]; then
  ok "T4 placeholder inventory matches documented set"
else
  bad "T4 placeholder inventory drift" "want: $WANT" "got:  $GOT"
fi

# ---- T5 routing reachability ----
T5_FAILS=()
for f in "$SKILL"/references/*.md; do
  b="references/$(basename "$f")"
  grep -q "$b" "$SKILL/SKILL.md" || T5_FAILS+=("MISS $b not referenced from SKILL.md")
done
while read -r ref; do
  [[ -f "$SKILL/$ref" ]] || T5_FAILS+=("MISS $ref referenced but absent")
done < <(grep -ohE 'references/[a-z0-9-]+\.md' "${FILES[@]}" | sort -u)
if [[ "${#T5_FAILS[@]}" -eq 0 ]]; then
  ok "T5 routing table reachability (SKILL.md <-> references/)"
else
  bad "T5 routing gaps:" "${T5_FAILS[@]}"
fi

# ---- T6 ASCII + LF ----
T6_FAILS=()
for f in "${FILES[@]}"; do
  if LC_ALL=C grep -q $'\r' "$f"; then T6_FAILS+=("CR bytes in ${f#$REPO/}"); fi
  if LC_ALL=C grep -qP '[^\x00-\x7F]' "$f"; then T6_FAILS+=("non-ASCII in ${f#$REPO/}"); fi
done
if [[ "${#T6_FAILS[@]}" -eq 0 ]]; then
  ok "T6 ASCII + LF clean"
else
  bad "T6 encoding:" "${T6_FAILS[@]}"
fi

# ---- T7 expected-refusal table ----
TS="$SKILL/references/troubleshooting.md"
if grep -qi 'expected refusal' "$TS" && grep -q '| Operation attempted |' "$TS"; then
  ok "T7 expected-refusal table present in troubleshooting.md"
else
  bad "T7 expected-refusal table missing from troubleshooting.md"
fi

# ---- T8 starter-script references + syntax ----
T8_FAILS=()
GUIDE="$REPO/clientdocs/ai-assistant-guide.md"
while read -r sh; do
  [[ -f "$REPO/clientdocs/scripts/$sh" ]] || T8_FAILS+=("MISS clientdocs/scripts/$sh referenced but absent")
done < <(grep -ohE 'scripts/[a-z0-9-]+\.sh' "${FILES[@]}" "$GUIDE" 2>/dev/null | sed 's|^scripts/||' | sort -u)
for s in "$REPO"/clientdocs/scripts/*.sh; do
  [[ -f "$s" ]] || continue
  bash -n "$s" 2>/dev/null || T8_FAILS+=("SYNTAX ${s#$REPO/} fails bash -n")
done
if [[ "${#T8_FAILS[@]}" -eq 0 ]]; then
  ok "T8 starter-script references exist and parse (bash -n)"
else
  bad "T8 starter-script gaps:" "${T8_FAILS[@]}"
fi

echo; echo "RESULT: PASS=$PASS FAIL=$FAIL"
[[ "$FAIL" -eq 0 ]] && { echo "ALL PASS"; exit 0; } || exit 1
