"""promptfoo assertion functions for NoiseGate triage evals."""

import json


def validate_schema(output, context):
    """Verify the output is valid JSON with the expected NoiseGate structure."""
    try:
        data = json.loads(output)
    except (json.JSONDecodeError, TypeError) as e:
        return {"pass": False, "score": 0, "reason": f"Invalid JSON: {e}"}

    required = ["checks", "summary", "verdict", "model_used"]
    missing = [k for k in required if k not in data]
    if missing:
        return {"pass": False, "score": 0, "reason": f"Missing keys: {missing}"}

    if not isinstance(data["checks"], list) or len(data["checks"]) == 0:
        return {"pass": False, "score": 0, "reason": "checks must be a non-empty list"}

    for check in data["checks"]:
        if not check.get("reason", "").strip():
            return {
                "pass": False,
                "score": 0.5,
                "reason": f"Empty reason for check '{check.get('check_id', '?')}'",
            }

    return {"pass": True, "score": 1.0, "reason": "Valid schema"}


def verdict_matches_expected(output, context):
    """Check that the verdict aligns with the expected verdict for this report."""
    try:
        data = json.loads(output)
    except (json.JSONDecodeError, TypeError):
        return {"pass": False, "score": 0, "reason": "Cannot parse output JSON"}

    verdict = data.get("verdict", "")
    expected = context["vars"].get("expected_verdict", "")

    if not expected:
        return {"pass": True, "score": 1.0, "reason": "No expected verdict specified"}

    if expected == "PASS":
        # Resolved reports should not be FAILed
        if verdict == "PASS":
            return {"pass": True, "score": 1.0, "reason": "Correct: PASS"}
        if verdict == "WARN":
            return {"pass": True, "score": 0.7, "reason": "Acceptable: WARN (expected PASS)"}
        return {"pass": False, "score": 0, "reason": f"Wrong: got {verdict}, expected PASS"}

    if expected == "FAIL":
        # Invalid reports should not PASS
        if verdict == "FAIL":
            return {"pass": True, "score": 1.0, "reason": "Correct: FAIL"}
        if verdict == "WARN":
            return {"pass": True, "score": 0.5, "reason": "Acceptable: WARN (expected FAIL)"}
        return {"pass": False, "score": 0, "reason": f"Wrong: got {verdict}, expected FAIL"}

    return {"pass": True, "score": 0.5, "reason": f"Unknown expected verdict: {expected}"}
