"""CRA Annex I -> NIST 800-53 Rev5 + OWASP Top 10:2021 crosswalk (Security Golden Set).

Deterministic, hand-curated mapping. It is the AUTHORITATIVE reference set that
the standalone CRA assessment uses to attach best-practice control IDs to each
CRA essential requirement. NOT a RAG search — semantic breadth comes later via
the shared Controls-API of the mapping session, NOT a second retrieval here.

Each entry maps a CRA-AI requirement to the well-established NIST 800-53 Rev5
control identifiers and the OWASP Top 10:2021 category that govern the same
control objective. Process-only requirements (disclosure/reporting) carry NIST
refs where defensible and no OWASP code (OWASP Top 10 addresses code-level
weaknesses, not disclosure processes) — left empty rather than invented.
"""

# OWASP Top 10:2021 category labels (for display).
OWASP_2021 = {
    "A01:2021": "Broken Access Control",
    "A02:2021": "Cryptographic Failures",
    "A04:2021": "Insecure Design",
    "A05:2021": "Security Misconfiguration",
    "A06:2021": "Vulnerable and Outdated Components",
    "A07:2021": "Identification and Authentication Failures",
    "A08:2021": "Software and Data Integrity Failures",
    "A09:2021": "Security Logging and Monitoring Failures",
}

# req_id -> {"nist": [800-53 control IDs], "owasp": [Top 10:2021 codes]}
CRA_SECURITY_CROSSWALK = {
    "CRA-AI-1":  {"nist": ["CM-6", "CM-7"], "owasp": ["A05:2021"]},
    "CRA-AI-2":  {"nist": ["CM-7", "SC-7"], "owasp": ["A05:2021"]},
    "CRA-AI-3":  {"nist": ["SA-8", "SC-7", "SC-39"], "owasp": ["A04:2021"]},
    "CRA-AI-4":  {"nist": ["AC-6"], "owasp": ["A01:2021"]},
    "CRA-AI-5":  {"nist": ["SI-7", "CM-5"], "owasp": ["A08:2021"]},
    "CRA-AI-6":  {"nist": ["SI-7"], "owasp": ["A08:2021"]},
    "CRA-AI-7":  {"nist": ["IA-2", "IA-2(1)"], "owasp": ["A07:2021"]},
    "CRA-AI-8":  {"nist": ["IA-5", "IA-5(1)"], "owasp": ["A07:2021"]},
    "CRA-AI-9":  {"nist": ["IA-5"], "owasp": ["A07:2021"]},
    "CRA-AI-10": {"nist": ["AC-12", "SC-23"], "owasp": ["A07:2021"]},
    "CRA-AI-11": {"nist": ["AC-7"], "owasp": ["A07:2021"]},
    "CRA-AI-12": {"nist": ["AC-2", "AC-3", "AC-6"], "owasp": ["A01:2021"]},
    "CRA-AI-13": {"nist": ["SC-13", "SC-28"], "owasp": ["A02:2021"]},
    "CRA-AI-14": {"nist": ["SC-28"], "owasp": ["A02:2021"]},
    "CRA-AI-15": {"nist": ["SC-8", "SC-8(1)"], "owasp": ["A02:2021"]},
    "CRA-AI-16": {"nist": ["SC-12"], "owasp": ["A02:2021"]},
    "CRA-AI-17": {"nist": ["SI-12"], "owasp": []},
    "CRA-AI-18": {"nist": ["SA-3", "SA-8", "SA-15"], "owasp": ["A04:2021"]},
    "CRA-AI-19": {"nist": ["SA-11", "SA-15"], "owasp": ["A04:2021"]},
    "CRA-AI-20": {"nist": ["SA-11", "SA-11(1)"], "owasp": ["A04:2021"]},
    "CRA-AI-21": {"nist": ["SR-3", "SR-5", "SR-6"], "owasp": ["A06:2021"]},
    "CRA-AI-22": {"nist": ["RA-5", "SI-2", "SR-4"], "owasp": ["A06:2021"]},
    "CRA-AI-23": {"nist": ["SR-4", "SR-3"], "owasp": ["A06:2021"]},
    "CRA-AI-24": {"nist": ["AU-2", "AU-3"], "owasp": ["A09:2021"]},
    "CRA-AI-25": {"nist": ["AU-6", "SI-4"], "owasp": ["A09:2021"]},
    "CRA-AI-26": {"nist": ["SI-4"], "owasp": ["A09:2021"]},
    "CRA-AI-27": {"nist": ["AU-9"], "owasp": ["A09:2021"]},
    "CRA-AI-28": {"nist": ["SI-2", "SI-7"], "owasp": ["A08:2021"]},
    "CRA-AI-29": {"nist": ["SI-7(15)", "SC-12"], "owasp": ["A08:2021"]},
    "CRA-AI-30": {"nist": ["SI-7"], "owasp": ["A08:2021"]},
    "CRA-AI-31": {"nist": ["SA-22"], "owasp": ["A06:2021"]},
    "CRA-AI-32": {"nist": ["RA-5"], "owasp": ["A06:2021"]},
    "CRA-AI-33": {"nist": ["RA-5", "SR-4"], "owasp": ["A06:2021"]},
    "CRA-AI-34": {"nist": ["RA-5", "RA-7"], "owasp": []},
    "CRA-AI-35": {"nist": ["SI-5"], "owasp": []},
    "CRA-AI-36": {"nist": ["IR-4", "IR-6"], "owasp": []},
    "CRA-AI-37": {"nist": ["IR-6"], "owasp": []},
    "CRA-AI-38": {"nist": ["IR-6", "IR-8"], "owasp": []},
    "CRA-AI-39": {"nist": ["SI-2"], "owasp": ["A06:2021"]},
    "CRA-AI-40": {"nist": ["IR-5", "AU-11"], "owasp": []},
}


def security_refs_for(req_ids: list) -> dict:
    """Union of NIST + OWASP refs across the given CRA-AI requirement ids.

    Returns {"nist": [...], "owasp": [{"code": .., "label": ..}]}, deduped,
    order-stable. The golden set is the single source — no retrieval.
    """
    nist: list = []
    owasp: list = []
    seen_owasp = set()
    for rid in req_ids:
        entry = CRA_SECURITY_CROSSWALK.get(rid)
        if not entry:
            continue
        for n in entry["nist"]:
            if n not in nist:
                nist.append(n)
        for code in entry["owasp"]:
            if code not in seen_owasp:
                seen_owasp.add(code)
                owasp.append({"code": code, "label": OWASP_2021.get(code, "")})
    return {"nist": nist, "owasp": owasp}
