"""Layer-3 Sufficiency-Judge fuer Cookie-Policy.

Das Embedding/Boost-Auto-Rescue (Layer 0/2) ist BEWUSST optimistisch — es findet
das Thema, beweist aber nicht die Erfuellung. Messung (2026-06-22): 159 FN
(Over-Rescue) gegen Opus-GT, weil 'Thema erwaehnt' als 'erfuellt' durchgewunken
wurde. Diese Schicht prueft GENAU die rescued Controls mit dem validierten
Haiku-Judge (Cohort cookie_sufficiency_v1: P0.89/R0.91) — NICHT die Qwen-first-
Kaskade (lokal ist als Sufficiency-Judge widerlegt) — und nimmt 'passed' zurueck,
wenn die konkrete Pflicht nicht erfuellt ist. 'Embedding findet, Claude entscheidet.'

Nur fuer den NICHT-skip_llm-Pfad (voller Check); der schnelle/interaktive Pfad
behaelt das deterministische Rescue.
"""

from __future__ import annotations

import logging
from typing import Any

logger = logging.getLogger(__name__)

_RESCUE_MARKERS = ("+embedding", "+regex_boost")


def _is_rescued(r: dict[str, Any]) -> bool:
    src = r.get("source") or ""
    return r.get("passed") and any(m in src for m in _RESCUE_MARKERS)


async def judge_rescued(text: str, results: list[dict[str, Any]]) -> int:
    """Prueft alle rescued (embedding/boost) passed-Controls mit Haiku.
    Nimmt passed zurueck, wenn der Judge die Pflicht als NICHT erfuellt sieht.
    Gibt die Anzahl zurueckgenommener (korrigierter) Rescues zurueck.
    """
    # Über den gemeinsamen Prüfer-Router (kein Cookie-Sonderfall mehr):
    # CONTENT/LLM → build_spec setzt judge='haiku' → LLMChecker (validierter
    # Sufficiency-Judge). Damit ist Cookie der erste echte Router-Consumer.
    from compliance.services.checkers.base import DocContext
    from compliance.services.checkers.router import build_spec, route_and_check

    candidates = [r for r in results if _is_rescued(r)]
    if not candidates:
        return 0
    doc = DocContext(text=text)
    sc = {"verification_method": "CONTENT", "decision_method": "LLM"}
    corrected = 0
    for r in candidates:
        crit = r.get("_pass_criteria") or [r.get("label") or r.get("hint") or ""]
        if not isinstance(crit, list):
            crit = [str(crit)]
        label = r.get("label") or r.get("hint") or r.get("control_id") or ""
        spec = build_spec(r.get("control_id") or "", sc, label=label, criteria=crit)
        res = await route_and_check(spec, doc)
        if res.present is False:
            r["passed"] = False
            r["source"] = (r.get("source") or "") + "+llm_failed"
            r["matched_text"] = "[layer-3 sufficiency-judge: nicht erfuellt]"
            r["_judge_reason"] = (res.evidence or "")[:200]
            corrected += 1
    if corrected:
        logger.info("cookie layer-3 sufficiency-judge: %d/%d rescues zurueckgenommen",
                    corrected, len(candidates))
    return corrected
