#!/usr/bin/env bash
set -e
cd "$(dirname "$0")"

# ---- Layer 0: parse gate ----------------------------------------------------
# Every shipped .lua must at least parse. A scripted edit shipped an unbalanced
# paren on 2026-06-11; nothing dofiles that controller, so only a parse pass can
# catch it. Homebrew luac may be 5.4 (a syntax superset of 5.1) -- this layer
# gates SYNTAX BREAKS; 5.1-only compliance stays with review.md + wowlua-ls.
parse_fail=0
echo "=== Layer 0: parse every shipped .lua ==="
for f in $(find ../Core ../Modules ../UI ../Locale ../Data -name '*.lua' 2>/dev/null); do
    if ! luac -p "$f" 2>/tmp/hdg_parse_err.txt; then
        parse_fail=$((parse_fail+1))
        cat /tmp/hdg_parse_err.txt
    fi
done
if [ "$parse_fail" -gt 0 ]; then
    echo "!! $parse_fail file(s) failed to parse"
else
    echo "   all shipped files parse"
fi

# ---- Lua test files --------------------------------------------------------
fail=0
for t in test_*.lua; do
    echo "=== $t ==="
    if ! lua "$t"; then
        fail=$((fail+1))
    fi
done

# ---- Lattice drift sweep (skill Tier-1) ------------------------------------
# sweep.py is maintained in the redux-style-wow-addon skill (source of truth --
# not copied into the repo so it never goes stale). Gate the suite on CRITICAL
# hits only (silent-failure modes: selector-read drift, async API in a selector).
# IMPORTANT/INFO are reported but NON-BLOCKING: the addon carries a known
# IMPORTANT backlog -- run `python3 <sweep> ..` directly to triage it.
sweep_crit=0
SWEEP="$HOME/.claude/skills/redux-style-wow-addon/scripts/sweep.py"
if [ -f "$SWEEP" ]; then
    echo ""
    echo "=== sweep.py (Lattice drift) ==="
    set +e
    sweep_out="$(python3 "$SWEEP" .. 2>&1)"
    sweep_rc=$?
    set -e
    # Severity summary only -- the full hit list lives behind a direct run.
    echo "$sweep_out" | grep -E "=== (CRITICAL|IMPORTANT|INFO)" || true
    if [ "$sweep_rc" -eq 1 ]; then
        sweep_crit=1
        echo "!! sweep: CRITICAL hits present. Review: python3 \"$SWEEP\" .."
        echo "$sweep_out" | awk '/=== CRITICAL/{p=1} /=== IMPORTANT/{p=0} p'
    elif [ "$sweep_rc" -eq 2 ]; then
        echo "   sweep: IMPORTANT/INFO present (non-blocking backlog). Review: python3 \"$SWEEP\" .."
    fi
else
    echo ""
    echo "(sweep.py not found at $SWEEP -- skipping Lattice drift sweep)"
fi

# ---- Semantic drift tier (data-flow: aliased-state cascades) ---------------
# Materializes the guaranteed state shape by RUNNING the addon's factories, then
# parses every source file with luacheck's real Lua AST and walks it with exact
# lexical scoping, flagging `local X = state.<seeded-path>; X and X.field` dead
# guards -- the class regex CAN'T reach (needs the assignment + the factory
# shape). The AST covers multi-line cascades, dotted-prefix aliases
# (HDG.Store.state.X), exact scope, and string/comment safety that the old
# line-based POC missed. Repo-local (scripts/semantic_sweep.lua; runs from root;
# needs luacheck -- exit 3 = skip if absent). Semantic-sweep hits are CRITICAL
# (data-flow drift hides silent staleness) -- they gate the suite, never a soft
# backlog. Boosted to CRITICAL severity 2026-05-31.
sem_fail=0
echo ""
echo "=== semantic_sweep (data-flow tier -- CRITICAL) ==="
set +e
( cd .. && lua scripts/semantic_sweep.lua )
sem_rc=$?
set -e
if [ "$sem_rc" -eq 1 ]; then
    sem_fail=1; echo "!! semantic_sweep: CRITICAL drift present (above) -- strict-read them, do NOT defer."
elif [ "$sem_rc" -eq 3 ]; then
    echo "   semantic_sweep: SKIPPED (luacheck not installed -- 'luarocks install luacheck')."
fi

# ---- luacheck lint tier (narrow: shadowing + control-flow) ------------------
# .luacheckrc deliberately ignores 1xx/2xx/3xx/6xx (wowlua-ls owns globals;
# unused-local is review judgement) -- what's left is 4xx shadowing (the
# duplicate-_paintRoomRow class) + 5xx control-flow smells. ERRORS always
# block; warnings gate on a count baseline (all triaged style-idioms as of
# 2026-06-11: not(x==y) forms, empty-if comments, first-key loops).
LC_BASELINE=42
lc_fail=0
echo ""
echo "=== luacheck (shadowing/control-flow -- count baseline $LC_BASELINE) ==="
if command -v luacheck >/dev/null; then
    set +e
    lc_out="$( cd .. && luacheck . --no-color 2>&1 )"
    lc_summary="$(printf '%s\n' "$lc_out" | tail -1)"
    echo "   $lc_summary"
    lc_errs="$(printf '%s\n' "$lc_summary" | grep -oE '[0-9]+ error' | grep -oE '[0-9]+')"
    lc_warns="$(printf '%s\n' "$lc_summary" | grep -oE '[0-9]+ warning' | grep -oE '[0-9]+')"
    set -e
    if [ "${lc_errs:-0}" -gt 0 ] || [ "${lc_warns:-0}" -gt "$LC_BASELINE" ]; then
        lc_fail=1
        echo "!! luacheck: errors or warning count above baseline $LC_BASELINE:"
        printf '%s\n' "$lc_out" | grep -E "\(W4|\(W5|\(E" | head -40
    fi
else
    echo "   luacheck: SKIPPED (not installed -- 'luarocks install luacheck')."
fi

# ---- WoW-API type-safety tier (wowlua-ls) ----------------------------------
# TSM's Rust WoW-Lua LS (built at ../../wowlua-ls). Knows the real 12.0.5 API
# surface -> catches wrong-arity / removed-API / struct-field bugs the regex
# (sweep.py) + data-flow (semantic_sweep) tiers structurally cannot. The current
# WLL_BASELINE warnings are ALL triaged stub/inference false-positives as of
# 2026-06-06 (custom frame fields, variadic pcall, return-arity under-counts,
# flavor-mask quirks, mixin Event tables, boundary-guarded enum reads, control-
# flow-guaranteed non-nil). So we gate on a COUNT BASELINE: fail only when the
# count RISES (a new warning = a candidate real bug to triage against the wow-api
# MCP). Soft-skip if the binary isn't built.
WLL_BASELINE=44
wll_fail=0
echo ""
echo "=== wowlua-ls (WoW-API type tier -- count baseline $WLL_BASELINE) ==="
if ( cd .. && [ -x ../wowlua-ls/target/release/wowlua_ls ] ); then
    set +e
    wll_out="$( cd .. && ../wowlua-ls/target/release/wowlua_ls check . 2>&1 )"
    set -e
    wll_n="$(printf '%s\n' "$wll_out" | grep -cE 'warning\[')"
    echo "   wowlua-ls: $wll_n warnings (baseline $WLL_BASELINE)"
    if [ "$wll_n" -gt "$WLL_BASELINE" ]; then
        wll_fail=1
        echo "!! wowlua-ls: $wll_n > baseline $WLL_BASELINE -- NEW diagnostic(s); triage vs the wow-api MCP:"
        printf '%s\n' "$wll_out" | grep -E 'warning\[' | head -60
    elif [ "$wll_n" -lt "$WLL_BASELINE" ]; then
        echo "   wowlua-ls: below baseline -- lower WLL_BASELINE to $wll_n in run_all.sh."
    fi
else
    echo "   wowlua-ls: SKIPPED (binary not built at wowlua-ls/target/release/wowlua_ls)."
fi

# ---- Verdict ---------------------------------------------------------------
if [ "$parse_fail" -gt 0 ] || [ "$fail" -gt 0 ] || [ "$sweep_crit" -gt 0 ] || [ "$sem_fail" -gt 0 ] || [ "$lc_fail" -gt 0 ] || [ "$wll_fail" -gt 0 ]; then
    [ "$parse_fail" -gt 0 ] && echo "$parse_fail file(s) failed to parse"
    [ "$fail" -gt 0 ]       && echo "$fail test files failed"
    [ "$sweep_crit" -gt 0 ] && echo "sweep: CRITICAL hits present"
    [ "$sem_fail" -gt 0 ]   && echo "semantic_sweep: CRITICAL drift present"
    [ "$lc_fail" -gt 0 ]    && echo "luacheck: errors or warning count above baseline"
    [ "$wll_fail" -gt 0 ]   && echo "wowlua-ls: warning count rose above baseline"
    exit 1
fi

echo "all files parse + tests passed + sweep clean + semantic tier clean + luacheck + wowlua-ls at/below baseline"
