#!/usr/bin/env python3
"""verify_challenges.py -- CI gate for the LintQ challenge example set.

Runs every example in ``challenges.json`` through both LintQ engines and
checks each detector's behaviour against the ground-truth labels using the
shared logic in ``challenge_lib.py``.

Exit code is non-zero if any *explicit* expectation is violated (a missing
FIRE -> FALSE_NEG, an unwanted fire on a SILENT example -> FALSE_POS, or a
regression of a documented limitation -> FALSE_POS(limitation)).  ``N/A``
rows (detectors out of scope for an example) are reported but never asserted,
so the gate is regression-catching rather than regression-hiding.

Usage:
    python3 examples/verify_challenges.py
"""

from __future__ import annotations

import os
import shutil
import sys

HERE = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, HERE)
import challenge_lib as lib  # noqa: E402


def main() -> int:
    if not shutil.which("souffle"):
        print("souffle not on PATH; cannot verify", file=sys.stderr)
        return 2

    results = lib.run_all()

    failures = 0
    last_ex = None
    for r in results:
        if r.ex_id != last_ex:
            print(f"\n### {r.ex_id}")
            last_ex = r.ex_id
        flag = "  <-- MISMATCH" if r.failed else ""
        if r.failed:
            failures += 1
        print(f"  {r.detector:14s} expected={r.expected:8s} "
              f"fired={r.did_fire!s:5s} -> {r.verdict}{flag}")

    print("\n" + "=" * 60)
    if failures:
        print(f"RESULT: {failures} detector expectation(s) MISMATCH")
        return 1
    print("RESULT: all ground-truth labels CONFIRMED by both engines")
    return 0


if __name__ == "__main__":
    sys.exit(main())
