"""Prüfer-Router — method-agnostischer Dispatch.

control → sensor_classification (verification_method + decision_method) → Checker.
Ein neues Modul liefert nur ControlSpecs; der Router wählt den Prüfer. Damit wird
der „Embedding findet, Claude entscheidet"-Pfad EIN gemeinsamer CONTENT/LLM-Prüfer
statt Cookie-Sonderlogik. Nicht-gebaute Prüfer (PLAYWRIGHT/AUDIT/SCANNER/REGEX-
FIELD) → present=None (fail-safe: Aufrufer behält sein deterministisches Ergebnis).
"""
from __future__ import annotations

from typing import Any, Optional

from .base import CheckResult, ControlSpec, DecisionMethod, DocContext
from .embedding_checker import EmbeddingChecker
from .llm_checker import LLMChecker
from .reference_checker import ReferenceChecker

_LLM = LLMChecker()
_EMB = EmbeddingChecker()
_REF = ReferenceChecker()

# decision_method → Checker. Fehlende Mechanismen bewusst None (noch nicht gebaut).
_BY_DECISION: dict[str, Any] = {
    DecisionMethod.LLM: _LLM,
    DecisionMethod.EMBEDDING: _EMB,
    DecisionMethod.LINK_RESOLVER: _REF,
}


async def route_and_check(ctrl: ControlSpec, doc: DocContext) -> CheckResult:
    checker = _BY_DECISION.get((ctrl.decision_method or "").upper())
    if checker is None:
        return CheckResult(present=None,
                           source=f"no_checker:{ctrl.decision_method}")
    return await checker.check(ctrl, doc)


def build_spec(
    control_id: str,
    sensor_classification: Optional[dict[str, Any]],
    *,
    label: str = "",
    criteria: Optional[list] = None,
    question: str = "",
    patterns: Optional[list[str]] = None,
    embed_threshold: Optional[float] = None,
) -> ControlSpec:
    """Baut ein ControlSpec aus der GESPEICHERTEN sensor_classification
    (canonical_controls.generation_metadata.sensor_classification) + den
    Control-Kriterien. CONTENT/LLM → judge='haiku' (validierter Sufficiency-
    Judge; Default für Sufficiency lt. Entscheidung 2026-06-22)."""
    sc = sensor_classification or {}
    vm = (sc.get("verification_method") or "").upper()
    dm = (sc.get("decision_method") or "").upper()
    extra: dict[str, Any] = {}
    if vm == "CONTENT" and dm == "LLM":
        extra["judge"] = "haiku"
    return ControlSpec(
        control_id=control_id,
        verification_method=vm,
        decision_method=dm,
        label=label,
        paraphrases=[str(c) for c in (criteria or []) if c],
        question=question,
        patterns=patterns or [],
        embed_threshold=embed_threshold,
        extra=extra,
    )
