"""CRA obligation scope rules.

`obligation_id`s in the six CRA-P1 families (sbom/vuln/authentication/logging/
remote_access/updates) are RE-USED verbatim from the Legal-KG registry
(`obligations/obligation_join_keys.json`) — never re-minted (control_uuid trap,
memory `project_compliance_graph.md`). Cross-cutting CRA *process* obligations
(risk assessment, technical documentation, CE, instructions, secure-by-design
umbrella) are not yet in the registry and are flagged `proposed=True`.
"""

from __future__ import annotations

from typing import List

from .enums import AuthorityLevel, Confidence
from .rules_types import ObligationRule

_HAS_SW = ("has_software", "eq", True)
_EU = ("eu_market", "eq", True)
_REMOTE_OR_CLOUD = {"any": [("has_remote_access", "eq", True), ("has_cloud_connection", "eq", True)]}
_LM = AuthorityLevel.LEGAL_TEXT

CRA_OBLIGATIONS: List[ObligationRule] = [
    ObligationRule(
        obligation_id="sbom_creation",
        title="Software Bill of Materials erstellen",
        source_regulation="CRA",
        obligation_text="Eine SBOM erstellen, die mindestens die obersten Abhängigkeiten des Produkts dokumentiert.",
        legal_basis_refs=["CRA Annex I Part II (1)"],
        authority_level=_LM,
        family="sbom",
        applies_if={"all": [_HAS_SW, _EU]},
        required_capabilities=["software_bill_of_materials"],
        required_evidence=["sbom", "repo_scan"],
        lifecycle_phase=["development", "placing_on_market", "maintenance"],
        registry_anchor=True,
    ),
    ObligationRule(
        obligation_id="provide_security_updates",
        title="Sicherheitsupdates bereitstellen",
        source_regulation="CRA",
        obligation_text="Sicherheitsrelevante Updates zeitnah und über den Supportzeitraum bereitstellen.",
        legal_basis_refs=["CRA Annex I (2)(c)", "CRA Art. 13"],
        authority_level=_LM,
        family="updates",
        applies_if={"all": [_HAS_SW, _EU]},
        required_capabilities=["secure_updates"],
        required_evidence=["policy", "ticket", "test_report"],
        lifecycle_phase=["maintenance", "update"],
        overlap_group_id="SECURITY_UPDATES",
        registry_anchor=True,
    ),
    ObligationRule(
        obligation_id="support_period_maintenance",
        title="Supportzeitraum definieren und einhalten",
        source_regulation="CRA",
        obligation_text="Einen angemessenen Supportzeitraum festlegen, in dem Schwachstellen behandelt werden.",
        legal_basis_refs=["CRA Art. 13(8)"],
        authority_level=_LM,
        family="updates",
        applies_if={"all": [_HAS_SW, _EU]},
        required_capabilities=["secure_updates"],
        required_evidence=["policy"],
        lifecycle_phase=["placing_on_market", "maintenance", "update"],
        registry_anchor=True,
    ),
    ObligationRule(
        obligation_id="signed_update_integrity",
        title="Integrität von Updates sicherstellen",
        source_regulation="CRA",
        obligation_text="Updates signieren und ihre Integrität bei der Verteilung verifizieren.",
        legal_basis_refs=["CRA Annex I (1)(3)(f)"],
        authority_level=_LM,
        family="updates",
        applies_if={"all": [_HAS_SW, _EU]},
        required_capabilities=["software_integrity"],
        required_evidence=["config_export", "test_report"],
        lifecycle_phase=["development", "maintenance", "update"],
        overlap_group_id="SECURITY_UPDATES",
        registry_anchor=True,
    ),
    ObligationRule(
        obligation_id="vuln_handling_process",
        title="Schwachstellenbehandlungs-Prozess",
        source_regulation="CRA",
        obligation_text="Einen dokumentierten Prozess zur Identifikation, Bewertung und Behebung von Schwachstellen betreiben.",
        legal_basis_refs=["CRA Art. 13(8)", "CRA Annex VII"],
        authority_level=_LM,
        family="vuln",
        applies_if={"all": [_HAS_SW, _EU]},
        required_capabilities=["vulnerability_management"],
        required_evidence=["policy", "ticket"],
        lifecycle_phase=["development", "operation", "maintenance"],
        overlap_group_id="VULNERABILITY_HANDLING",
        registry_anchor=True,
    ),
    ObligationRule(
        obligation_id="coordinated_vulnerability_disclosure",
        title="Coordinated Vulnerability Disclosure",
        source_regulation="CRA",
        obligation_text="Eine Richtlinie zur koordinierten Offenlegung von Schwachstellen bereitstellen.",
        legal_basis_refs=["CRA Annex I Part II (5)"],
        authority_level=_LM,
        family="vuln",
        applies_if={"all": [_HAS_SW, _EU]},
        required_capabilities=["coordinated_disclosure"],
        required_evidence=["policy"],
        lifecycle_phase=["operation", "maintenance"],
        overlap_group_id="VULNERABILITY_HANDLING",
        registry_anchor=True,
    ),
    ObligationRule(
        obligation_id="exploited_vuln_reporting_authorities",
        title="Meldung aktiv ausgenutzter Schwachstellen / Vorfälle",
        source_regulation="CRA",
        obligation_text="Aktiv ausgenutzte Schwachstellen und schwerwiegende Vorfälle an die zuständigen Behörden melden.",
        legal_basis_refs=["CRA Art. 14", "CRA Art. 16"],
        authority_level=_LM,
        family="vuln",
        applies_if={"all": [_HAS_SW, _EU]},
        required_capabilities=["incident_reporting"],
        required_evidence=["policy", "ticket"],
        lifecycle_phase=["operation", "maintenance"],
        registry_anchor=True,
    ),
    ObligationRule(
        obligation_id="user_authentication_required",
        title="Authentifizierung vorsehen",
        source_regulation="CRA",
        obligation_text="Den Zugang über einen geeigneten Authentifizierungsmechanismus schützen.",
        legal_basis_refs=["CRA Annex I (2)(d)"],
        authority_level=_LM,
        family="authentication",
        applies_if={"all": [_HAS_SW, _EU]},
        required_capabilities=["authentication"],
        required_evidence=["config_export", "pentest"],
        lifecycle_phase=["development", "operation"],
        registry_anchor=True,
    ),
    ObligationRule(
        obligation_id="no_default_credentials",
        title="Keine unveränderlichen Standard-Zugangsdaten",
        source_regulation="CRA",
        obligation_text="Sichere Standardkonfiguration; keine fest hinterlegten oder unveränderlichen Standard-Passwörter.",
        legal_basis_refs=["CRA Annex I (2)(a)", "CRA Annex I (2)(b)"],
        authority_level=_LM,
        family="authentication",
        applies_if={"all": [_HAS_SW, _EU]},
        required_capabilities=["secure_by_default"],
        required_evidence=["config_export", "test_report"],
        lifecycle_phase=["development", "placing_on_market"],
        registry_anchor=True,
    ),
    ObligationRule(
        obligation_id="event_logging_security_events",
        title="Sicherheitsrelevante Ereignisse protokollieren",
        source_regulation="CRA",
        obligation_text="Sicherheitsrelevante Ereignisse und Zugriffe aufzeichnen, um Vorfälle nachvollziehen zu können.",
        legal_basis_refs=["CRA Annex I Part I (2)(k)"],
        authority_level=_LM,
        family="logging",
        applies_if={"all": [_HAS_SW, _EU]},
        required_capabilities=["security_logging"],
        required_evidence=["config_export", "audit_log"],
        lifecycle_phase=["operation", "maintenance"],
        registry_anchor=True,
    ),
    ObligationRule(
        obligation_id="remote_access_attack_surface_min",
        title="Angriffsfläche minimieren",
        source_regulation="CRA",
        obligation_text="Die Angriffsfläche begrenzen, insbesondere exponierte Remote-/Cloud-Schnittstellen.",
        legal_basis_refs=["CRA Annex I (1)(2)(a)"],
        authority_level=_LM,
        family="remote_access",
        applies_if={"all": [_REMOTE_OR_CLOUD, _EU]},
        required_capabilities=["secure_by_default"],
        required_evidence=["config_export", "repo_scan", "pentest"],
        lifecycle_phase=["development", "operation"],
        registry_anchor=True,
    ),
    ObligationRule(
        obligation_id="remote_access_confidentiality_integrity",
        title="Vertraulichkeit/Integrität der Fernverbindung",
        source_regulation="CRA",
        obligation_text="Daten bei Fernzugriff/Cloud-Anbindung verschlüsselt und integritätsgeschützt übertragen.",
        legal_basis_refs=["CRA Annex I (1)(2)(b)", "CRA Annex I (1)(2)(c)"],
        authority_level=_LM,
        family="remote_access",
        applies_if={"all": [_REMOTE_OR_CLOUD, _EU]},
        required_capabilities=["secure_communication"],
        required_evidence=["config_export", "pentest"],
        lifecycle_phase=["operation"],
        registry_anchor=True,
    ),
    # --- Cross-cutting CRA process obligations (not yet in registry) ---------
    ObligationRule(
        obligation_id="cra_secure_by_design",
        title="Security by Design",
        source_regulation="CRA",
        obligation_text="Das Produkt so entwerfen, entwickeln und herstellen, dass ein angemessenes Cybersicherheitsniveau gewährleistet ist.",
        legal_basis_refs=["CRA Annex I Part I (1)"],
        authority_level=_LM,
        family="cra_process",
        applies_if={"all": [_HAS_SW, _EU]},
        required_capabilities=["secure_by_default", "risk_assessment"],
        required_evidence=["policy", "test_report"],
        lifecycle_phase=["development", "placing_on_market"],
        proposed=True,
    ),
    ObligationRule(
        obligation_id="cra_risk_assessment",
        title="Cybersicherheits-Risikobewertung",
        source_regulation="CRA",
        obligation_text="Eine Cybersicherheits-Risikobewertung durchführen und dokumentieren; in die technische Dokumentation aufnehmen.",
        legal_basis_refs=["CRA Art. 13(2)", "CRA Annex I Part I (1)"],
        authority_level=_LM,
        family="cra_process",
        applies_if={"all": [_HAS_SW, _EU]},
        required_capabilities=["risk_assessment"],
        required_evidence=["policy"],
        lifecycle_phase=["development", "placing_on_market"],
        overlap_group_id="RISK_ASSESSMENT",
        proposed=True,
    ),
    ObligationRule(
        obligation_id="cra_technical_documentation",
        title="Technische Dokumentation",
        source_regulation="CRA",
        obligation_text="Technische Dokumentation erstellen und aktuell halten, die Konformität mit den Anforderungen belegt.",
        legal_basis_refs=["CRA Art. 31", "CRA Annex VII"],
        authority_level=_LM,
        family="cra_process",
        applies_if={"all": [_HAS_SW, _EU]},
        required_capabilities=["technical_documentation"],
        required_evidence=["policy"],
        lifecycle_phase=["placing_on_market", "maintenance"],
        overlap_group_id="TECHNICAL_DOCUMENTATION",
        proposed=True,
    ),
    ObligationRule(
        obligation_id="cra_ce_conformity_assessment",
        title="Konformitätsbewertung / CE-Kennzeichnung",
        source_regulation="CRA",
        obligation_text="Vor dem Inverkehrbringen das passende Konformitätsbewertungsverfahren durchlaufen und CE kennzeichnen.",
        legal_basis_refs=["CRA Art. 32", "CRA Art. 28"],
        authority_level=_LM,
        family="cra_process",
        applies_if={"all": [_HAS_SW, _EU]},
        required_capabilities=["conformity_assessment"],
        required_evidence=["test_report", "policy"],
        lifecycle_phase=["placing_on_market"],
        overlap_group_id="CE_CONFORMITY",
        proposed=True,
    ),
    ObligationRule(
        obligation_id="cra_instructions_for_use",
        title="Informationen und Anweisungen für Nutzer",
        source_regulation="CRA",
        obligation_text="Nutzern verständliche Sicherheitsinformationen und -anweisungen bereitstellen (z. B. zu Updates und Support-Ende).",
        legal_basis_refs=["CRA Annex II"],
        authority_level=_LM,
        family="cra_process",
        applies_if={"all": [_HAS_SW, _EU]},
        required_capabilities=["technical_documentation"],
        required_evidence=["policy"],
        lifecycle_phase=["placing_on_market"],
        overlap_group_id="INSTRUCTIONS_FOR_USE",
        proposed=True,
    ),
]
