"""Tests for deterministic explanation generation."""

from __future__ import annotations

from unittest.mock import patch

from complyform.core.assessor.control_matcher import Finding
from complyform.core.explainer.deterministic import explain_finding
from complyform.core.explainer.models import Explanation
from complyform.core.profiles.models import Control


def _make_finding(**overrides: object) -> Finding:
    defaults: dict[str, object] = {
        "control_id": "1.1",
        "framework": "cis_gcp",
        "resource_address": "google_compute_instance.web",
        "resource_type": "google_compute_instance",
        "status": "FAIL",
        "severity": "HIGH",
        "finding": "Instance does not use shielded VM",
        "remediation": "Enable shielded VM in instance config",
        "checkov_id": "CKV_GCP_39",
        "cross_mappings": None,
        "native_ids": None,
        "confidence": "high",
    }
    defaults.update(overrides)
    return Finding.model_validate(defaults)


class TestExplainFinding:
    def test_returns_explanation_model(self) -> None:
        finding = _make_finding()
        result = explain_finding(finding)
        assert isinstance(result, Explanation)

    def test_fields_populated(self) -> None:
        finding = _make_finding()
        result = explain_finding(finding)
        assert result.control_id == "1.1"
        assert result.framework == "cis_gcp"
        assert result.severity == "HIGH"
        assert result.status == "FAIL"
        assert result.resource_address == "google_compute_instance.web"
        assert result.ai_generated is False
        assert result.model is None
        assert result.cached is False

    def test_summary_contains_resource(self) -> None:
        finding = _make_finding()
        result = explain_finding(finding)
        assert "google_compute_instance.web" in result.summary

    def test_remediation_hint_uses_remediation(self) -> None:
        finding = _make_finding(remediation="Enable shielded VM")
        result = explain_finding(finding)
        assert "Enable shielded VM" in result.remediation_hint

    def test_pass_status_no_action_needed(self) -> None:
        finding = _make_finding(status="PASS")
        result = explain_finding(finding)
        assert "No action needed" in result.remediation_hint

    def test_control_lookup_enriches_title(self) -> None:
        mock_control = Control(
            id="1.1",
            title="Ensure shielded VM",
            description="Shielded VMs protect against rootkits",
            severity="high",
            section="1",
            family="Compute",
        )
        with patch(
            "complyform.core.explainer.deterministic.get_control",
            return_value=mock_control,
        ):
            finding = _make_finding()
            result = explain_finding(finding)
            assert result.title == "Ensure shielded VM"
            assert "rootkits" in result.why_it_matters

    def test_control_not_found_uses_finding_text(self) -> None:
        with patch(
            "complyform.core.explainer.deterministic.get_control",
            return_value=None,
        ):
            finding = _make_finding(finding="Instance lacks encryption")
            result = explain_finding(finding)
            assert result.title == "Instance lacks encryption"

    def test_severity_rationale_populated(self) -> None:
        finding = _make_finding(severity="CRITICAL")
        result = explain_finding(finding)
        assert "CRITICAL" in result.severity_rationale
        assert "Immediate action" in result.severity_rationale

    def test_severity_not_in_why_it_matters(self) -> None:
        finding = _make_finding(severity="HIGH")
        result = explain_finding(finding)
        assert "Severity:" not in result.why_it_matters

    def test_empty_remediation_fallback(self) -> None:
        finding = _make_finding(remediation="")
        result = explain_finding(finding)
        assert "Review the control requirements" in result.remediation_hint
