"""Tests fuer das Use-Case-Register (Phase 0)."""

from __future__ import annotations

from compliance.data import use_case_registry as reg


def test_keys_unique_and_nonempty():
    keys = [uc.key for uc in reg._USE_CASES]
    assert len(keys) == len(set(keys))
    for uc in reg._USE_CASES:
        assert uc.key and uc.label
        assert uc.group in reg.USE_CASE_GROUPS


def test_every_use_case_has_a_verification_method_in_taxonomy():
    for uc in reg._USE_CASES:
        assert uc.verification_methods, uc.key
        for m in uc.verification_methods:
            assert m in reg.VERIFICATION_METHODS, (uc.key, m)


def test_not_only_document_use_cases():
    # Der entscheidende Punkt (User-Vorgabe): >=50% Source-Code/IT-Prozess.
    keys = set(reg.REGISTRY)
    for k in ("code_security", "network_security", "cra", "isms", "tisax"):
        assert k in keys
    methods = {m for uc in reg._USE_CASES for m in uc.verification_methods}
    assert {"source_code", "network", "it_process"} <= methods


def test_scope_tokens_cover_migration_145():
    # Alle bedeutungstragenden Migration-145-scope_doc_type-Werte ('other'
    # ausgenommen) sind mindestens einem Use Case zugeordnet.
    meaningful = {
        "cookie_richtlinie", "dse", "banner_implementation", "cmp_audit",
        "tom", "avv", "jc", "impressum", "agb", "widerruf", "process",
        "accounting",
    }
    assert meaningful <= set(reg.scope_token_to_use_cases)


def test_taxonomy_for_prompt_lists_all_enabled():
    txt = reg.taxonomy_for_prompt()
    for uc in reg.enabled_use_cases():
        assert uc.key in txt
    for m in reg.VERIFICATION_METHODS:
        assert m in txt


def test_validators():
    assert reg.is_valid_use_case("impressum")
    assert not reg.is_valid_use_case("ghost")
    assert reg.is_valid_verification_method("source_code")
    assert not reg.is_valid_verification_method("telepathy")


def test_evidence_mapping():
    assert reg.evidence_to_verification_method("code") == "source_code"
    assert reg.evidence_to_verification_method("code_review") == "source_code"
    assert reg.evidence_to_verification_method("process") == "it_process"
    assert reg.evidence_to_verification_method("document") == "document"
    assert reg.evidence_to_verification_method(None) is None
    assert reg.evidence_to_verification_method("xyz") is None


def test_registry_hash_stable_and_hex():
    h1 = reg.registry_hash()
    assert h1 == reg.registry_hash()
    assert len(h1) == 64 and all(c in "0123456789abcdef" for c in h1)


def test_frontend_list_shape():
    fl = reg.frontend_list()
    assert len(fl) == len(reg.enabled_use_cases())
    for e in fl:
        assert set(e) == {"key", "label", "group", "verification_methods"}


# ── Seed-Klassifizierung (Phase 1) ──────────────────────────────────


def test_seed_scope_token_to_use_case():
    ucs, _ = reg.seed_classify(scopes=["impressum"])
    assert "impressum" in ucs


def test_seed_category_to_use_case():
    ucs, _ = reg.seed_classify(categories=["network"])
    assert "network_security" in ucs


def test_seed_verification_method_from_evidence_and_method():
    _, m = reg.seed_classify(etypes=["code"])
    assert m == "source_code"
    _, m2 = reg.seed_classify(vmethods=["document"])
    assert m2 == "document"
    _, m3 = reg.seed_classify(etypes=["process"])
    assert m3 == "it_process"


def test_seed_multi_label():
    # scope 'process' haengt an mehreren Use Cases (dsr/loeschkonzept/dsfa)
    ucs, _ = reg.seed_classify(scopes=["process"])
    assert len(ucs) >= 2


def test_seed_empty_and_none_safe():
    ucs, m = reg.seed_classify(scopes=[None], categories=[None],
                               vmethods=[None], etypes=[None])
    assert ucs == [] and m is None
    assert reg.seed_classify() == ([], None)


# ── Deterministischer Regulierung→Use-Case-Mapper ───────────────────


def test_regulation_mapper_known():
    cases = {
        "OWASP Top 10 (2021)": "code_security",
        "NIST SP 800-207 (Zero Trust)": "network_security",
        "Cyber Resilience Act (CRA)": "cra",
        "DSGVO (EU) 2016/679": "dse",
        "EDPB Facial Recognition": "dse",      # Leitlinie → Datenschutz
        "TKG": "telekommunikation",            # Telekom-Recht, NICHT Impressum
        "TMG": "impressum",                    # echtes Impressumsrecht
        "TDDDG": "cookie_banner",
        "Markets in Crypto-Assets (MiCA)": "mica",
        "BGB": "agb",
    }
    for reg_str, expected in cases.items():
        assert reg.use_case_for_regulation(reg_str) == expected, reg_str


def test_regulation_mapper_impressum_misroutes_fixed():
    # Phase A: Telekom-/Datenschutz-/Gewerbe-Gesetze duerfen NICHT mehr als
    # Impressum durchgehen (Korpus enthaelt kein echtes Impressumsrecht ausser
    # TMG/MStV). Siehe Audit 2026-06-09.
    assert reg.use_case_for_regulation("Telekommunikationsgesetz Oesterreich") \
        == "telekommunikation"
    assert reg.use_case_for_regulation("DSK OH Telemedien") == "dse"
    assert reg.use_case_for_regulation("Gewerbeordnung (GewO)") == "handelsrecht"
    # Die echten Impressum-Quellen bleiben Impressum:
    assert reg.use_case_for_regulation("TMG") == "impressum"
    assert reg.use_case_for_regulation("AT Mediengesetz") == "impressum"


def test_regulation_mapper_abgb_before_bgb():
    # 'ABGB' enthaelt 'bgb' — die abgb-Regel MUSS zuerst greifen.
    assert reg.use_case_for_regulation("AT ABGB") == "handelsrecht"


def test_regulation_mapper_unknown_returns_none():
    assert reg.use_case_for_regulation("Voellig Unbekanntes Gesetz") is None
    assert reg.use_case_for_regulation(None) is None


def test_all_regulation_rules_point_to_valid_use_cases():
    for _needle, uc in reg._REGULATION_RULES:
        assert uc in reg.REGISTRY, uc
        assert reg.REGISTRY[uc].enabled
