"""SBOM/DAST normalization from the scanner MCP -> CRA finding shape + mapping.

Shapes pinned from the live MCP (sbom_vuln_report / list_dast_findings, 2026-06-18).
"""
import json

from compliance.services.scanner_mcp_client import normalize_sbom_report, normalize_dast
from compliance.services.cra_finding_mapper import ScannerFinding, map_finding

SBOM = json.dumps({
    "repo_id": "r1",
    "vulnerable_packages_count": 1,
    "total_vulnerabilities": 3,
    "packages": [
        {"name": "dompurify", "version": "3.3.3", "package_manager": "npm",
         "license": "MIT", "vulnerabilities": [
             {"id": "GHSA-39q2", "source": "osv", "severity": None},
             {"id": "GHSA-39q2", "source": "osv", "severity": None},   # dup
             {"id": "GHSA-76mc", "source": "osv", "severity": "high"}]},
        {"name": "clean-pkg", "version": "1.0", "package_manager": "npm",
         "vulnerabilities": []},   # no vulns -> skipped
    ],
})

DAST = json.dumps([
    {"_id": {"$oid": "abc123"}, "vuln_type": "security_misconfiguration",
     "title": "SQL backup exposure: /backup.sql", "description": "Sensitive resource accessible.",
     "severity": "high", "cwe": "CWE-16", "endpoint": "https://demo.x/backup.sql",
     "method": "GET", "exploitable": True},
])


class TestSbom:
    def test_one_finding_per_vulnerable_package(self):
        out = normalize_sbom_report(SBOM)
        assert len(out) == 1                      # clean-pkg skipped
        f = out[0]
        assert f["scan_type"] == "dependency"
        assert f["cwe"] == "CWE-1395"
        assert f["location"] == "npm:dompurify@3.3.3"
        assert f["severity"] == "high"            # escalated from the one graded vuln
        assert "GHSA-39q2" in f["description"] and "GHSA-76mc" in f["description"]

    def test_maps_to_dependency_requirement_even_with_keyword_in_name(self):
        # CWE path dominates → CRA-AI-22, not CRA-AI-20 from a "sql"-like name
        out = normalize_sbom_report(json.dumps({
            "repo_id": "r", "packages": [
                {"name": "sqlite3", "version": "5.0", "package_manager": "npm",
                 "vulnerabilities": [{"id": "CVE-x", "severity": "medium"}]}]}))
        m = map_finding(ScannerFinding.from_dict(out[0]))
        assert m.primary_requirement == "CRA-AI-22"

    def test_bad_json(self):
        assert normalize_sbom_report("not json") == []
        assert normalize_sbom_report("{}") == []


class TestDast:
    def test_normalizes_dast_finding(self):
        out = normalize_dast(DAST)
        assert len(out) == 1
        f = out[0]
        assert f["scan_type"] == "dast"
        assert f["cwe"] == "CWE-16"
        assert f["location"] == "https://demo.x/backup.sql"
        assert f["exploited"] is True
        assert "security_misconfiguration" in f["description"]

    def test_dast_maps_via_cwe(self):
        out = normalize_dast(DAST)
        m = map_finding(ScannerFinding.from_dict(out[0]))
        assert m.primary_requirement == "CRA-AI-1"   # CWE-16 -> secure config
        assert m.finding_id == "abc123"               # _id.$oid extracted

    def test_empty(self):
        assert normalize_dast("[]") == []
        assert normalize_dast("not json") == []
