"""Tests for complyform.reporting.sarif_report.format_sarif_report."""

from __future__ import annotations

from complyform.core.assessor.control_matcher import Finding
from complyform.reporting.sarif_report import format_sarif_report


def _make_finding(
    control_id: str = "CC6.1",
    framework: str = "soc2",
    status: str = "FAIL",
    severity: str = "HIGH",
    resource_address: str = "module.test.google_compute_instance.main",
) -> Finding:
    return Finding(
        control_id=control_id,
        framework=framework,
        resource_address=resource_address,
        resource_type="google_compute_instance",
        status=status,
        severity=severity,
        finding=f"Control {control_id} failed",
        remediation="Apply remediation",
        checkov_id="CKV_GCP_1",
        cross_mappings=None,
        native_ids=None,
        confidence="high",
    )


class TestOnlyFailInResults:
    def test_only_fail_findings_in_results(self) -> None:
        findings = [
            _make_finding(status="FAIL"),
            _make_finding(control_id="CC6.2", status="PASS"),
            _make_finding(control_id="CC7.1", status="MANUAL_REVIEW"),
            _make_finding(control_id="CC7.2", status="NOT_ASSESSED"),
        ]
        sarif = format_sarif_report(findings, cloud="gcp", frameworks=["soc2"])
        results = sarif["runs"][0]["results"]
        assert len(results) == 1
        assert results[0]["ruleId"] == "CC6.1"


class TestAllControlsInRules:
    def test_all_controls_appear_in_rules(self) -> None:
        findings = [
            _make_finding(control_id="CC6.1", status="FAIL"),
            _make_finding(control_id="CC6.2", status="PASS"),
            _make_finding(control_id="CC7.1", status="FAIL"),
        ]
        sarif = format_sarif_report(findings, cloud="gcp", frameworks=["soc2"])
        rules = sarif["runs"][0]["tool"]["driver"]["rules"]
        rule_ids = {r["id"] for r in rules}
        assert rule_ids == {"CC6.1", "CC6.2", "CC7.1"}


class TestSeverityMapping:
    def test_critical_maps_to_error(self) -> None:
        f = _make_finding(severity="CRITICAL")
        sarif = format_sarif_report([f], cloud="gcp", frameworks=["soc2"])
        assert sarif["runs"][0]["results"][0]["level"] == "error"

    def test_high_maps_to_error(self) -> None:
        f = _make_finding(severity="HIGH")
        sarif = format_sarif_report([f], cloud="gcp", frameworks=["soc2"])
        assert sarif["runs"][0]["results"][0]["level"] == "error"

    def test_medium_maps_to_warning(self) -> None:
        f = _make_finding(severity="MEDIUM")
        sarif = format_sarif_report([f], cloud="gcp", frameworks=["soc2"])
        assert sarif["runs"][0]["results"][0]["level"] == "warning"

    def test_low_maps_to_note(self) -> None:
        f = _make_finding(severity="LOW")
        sarif = format_sarif_report([f], cloud="gcp", frameworks=["soc2"])
        assert sarif["runs"][0]["results"][0]["level"] == "note"


class TestFingerprintDeterministic:
    def test_same_inputs_produce_same_fingerprint(self) -> None:
        f = _make_finding()
        sarif1 = format_sarif_report([f], cloud="gcp", frameworks=["soc2"])
        sarif2 = format_sarif_report([f], cloud="gcp", frameworks=["soc2"])
        fp1 = sarif1["runs"][0]["results"][0]["fingerprints"]["complyform/v1"]
        fp2 = sarif2["runs"][0]["results"][0]["fingerprints"]["complyform/v1"]
        assert fp1 == fp2

    def test_fingerprint_is_sha256_hex(self) -> None:
        f = _make_finding()
        sarif = format_sarif_report([f], cloud="gcp", frameworks=["soc2"])
        fp = sarif["runs"][0]["results"][0]["fingerprints"]["complyform/v1"]
        # SHA-256 hex is 64 chars
        assert len(fp) == 64
        int(fp, 16)  # should not raise

    def test_different_resource_different_fingerprint(self) -> None:
        f1 = _make_finding(resource_address="addr_a")
        f2 = _make_finding(resource_address="addr_b")
        s1 = format_sarif_report([f1], cloud="gcp", frameworks=["soc2"])
        s2 = format_sarif_report([f2], cloud="gcp", frameworks=["soc2"])
        fp1 = s1["runs"][0]["results"][0]["fingerprints"]["complyform/v1"]
        fp2 = s2["runs"][0]["results"][0]["fingerprints"]["complyform/v1"]
        assert fp1 != fp2


class TestSarifVersion:
    def test_version_is_2_1_0(self) -> None:
        f = _make_finding()
        sarif = format_sarif_report([f], cloud="gcp", frameworks=["soc2"])
        assert sarif["version"] == "2.1.0"
