"""Tests for cross-validation matching logic."""

from __future__ import annotations

from typing import Any

from complyform.core.assessor.control_matcher import Finding
from complyform.core.cloud_intelligence.cross_validator import (
    NativeFinding,
    format_native_only_gaps,
    match_findings,
)


def _make_finding(
    control_id: str = "CC6.1",
    framework: str = "soc2",
    resource_address: str = "google_compute_instance.vm1",
    resource_type: str = "google_compute_instance",
    native_ids: dict[str, Any] | None = None,
) -> Finding:
    return Finding(
        control_id=control_id,
        framework=framework,
        resource_address=resource_address,
        resource_type=resource_type,
        status="FAIL",
        severity="HIGH",
        finding="Test finding",
        remediation="Fix it",
        checkov_id="CKV_GCP_1",
        cross_mappings=None,
        native_ids=native_ids,
        confidence="high",
    )


def _make_native(
    native_id: str = "DETECTOR_1",
    resource_id: str = "google_compute_instance.vm1",
    resource_type: str = "compute",
) -> NativeFinding:
    return NativeFinding(
        native_id=native_id,
        resource_id=resource_id,
        resource_type=resource_type,
        severity="HIGH",
        title="Test",
        status="ACTIVE",
    )


class TestMatchFindings:
    def test_resource_match(self) -> None:
        cf = [_make_finding(resource_address="google_compute_instance.vm1")]
        nf = [_make_native(resource_id="raw_id", resource_type="compute")]

        def normalize(rid: str, rtype: str) -> str | None:
            return "google_compute_instance.vm1"

        result = match_findings(cf, nf, normalize)
        assert len(result.confirmed) == 1
        assert result.confirmed[0].match_type == "resource_match"
        assert len(result.complyform_only) == 0
        assert len(result.native_only) == 0

    def test_control_match(self) -> None:
        cf = [
            _make_finding(
                resource_address="different",
                native_ids={"scc": "DETECTOR_1"},
            )
        ]
        nf = [_make_native(native_id="DETECTOR_1", resource_id="raw")]

        def normalize(rid: str, rtype: str) -> str | None:
            return "something_else"

        result = match_findings(cf, nf, normalize)
        assert len(result.confirmed) == 1
        assert result.confirmed[0].match_type == "control_match"

    def test_both_match(self) -> None:
        cf = [
            _make_finding(
                resource_address="google_compute_instance.vm1",
                native_ids={"scc": "DETECTOR_1"},
            )
        ]
        nf = [_make_native(native_id="DETECTOR_1", resource_id="raw")]

        def normalize(rid: str, rtype: str) -> str | None:
            return "google_compute_instance.vm1"

        result = match_findings(cf, nf, normalize)
        assert len(result.confirmed) == 1
        assert result.confirmed[0].match_type == "both"

    def test_three_cf_two_native_one_match(self) -> None:
        cf = [
            _make_finding(resource_address="a.1"),
            _make_finding(resource_address="a.2"),
            _make_finding(resource_address="a.3"),
        ]
        nf = [
            _make_native(resource_id="raw1"),
            _make_native(resource_id="raw2"),
        ]

        def normalize(rid: str, rtype: str) -> str | None:
            if rid == "raw1":
                return "a.1"
            return None

        result = match_findings(cf, nf, normalize)
        assert len(result.confirmed) == 1
        assert len(result.complyform_only) == 2
        assert len(result.native_only) == 1

    def test_empty_native(self) -> None:
        cf = [_make_finding()]
        result = match_findings(cf, [])
        assert len(result.complyform_only) == 1
        assert result.cross_validation_score == 0

    def test_score_calculation(self) -> None:
        cf = [_make_finding(resource_address="a.1")]
        nf = [_make_native(resource_id="raw")]

        def normalize(rid: str, rtype: str) -> str | None:
            return "a.1"

        result = match_findings(cf, nf, normalize)
        assert result.cross_validation_score == 100

    def test_empty_both(self) -> None:
        result = match_findings([], [])
        assert result.cross_validation_score == 0


class TestFormatNativeOnlyGaps:
    def test_gap_format(self) -> None:
        nf = [_make_native(native_id="XSS_SCRIPTING", resource_type="compute")]
        text = format_native_only_gaps(nf, "gcp")
        assert "Profile Gap Detected" in text
        assert "XSS_SCRIPTING" in text
        assert "compute" in text
        assert "gcp" in text

    def test_empty(self) -> None:
        text = format_native_only_gaps([], "aws")
        assert text == ""
