"""Tests for generic GRC JSON exporter."""

from __future__ import annotations

import json
from typing import TYPE_CHECKING

import pytest

from complyform.core.generators.evidence_export.grc_json import GrcJsonExporter

if TYPE_CHECKING:
    from pathlib import Path


@pytest.fixture
def exporter() -> GrcJsonExporter:
    return GrcJsonExporter()


@pytest.fixture
def metadata() -> dict[str, object]:
    return {"scan_id": "abc12345", "timestamp": "2024-01-01T00:00:00Z", "cloud": "gcp"}


@pytest.fixture
def sample_findings() -> list[dict[str, object]]:
    return [
        {
            "control_id": "CC6.1",
            "framework": "soc2",
            "resource_address": "google_sql_database_instance.main",
            "resource_type": "google_sql_database_instance",
            "status": "FAIL",
            "severity": "CRITICAL",
            "finding": "Encryption not enabled",
            "remediation": "Enable encryption",
            "checkov_id": "CKV_GCP_6",
            "native_ids": {"scc": "SQL_CMEK_DISABLED"},
            "cross_mappings": None,
            "confidence": "verified",
        },
    ]


class TestGrcJsonExporter:
    def test_format_id(self, exporter: GrcJsonExporter) -> None:
        assert exporter.FORMAT_ID == "grc-json"
        assert exporter.TIER_FEATURE == "evidence_export_native"

    def test_finding_id_format(
        self,
        exporter: GrcJsonExporter,
        sample_findings: list[dict[str, object]],
        metadata: dict[str, object],
        tmp_path: Path,
    ) -> None:
        result = exporter.export_to_file(sample_findings, metadata, tmp_path)
        json_files = [f for f in result.output_files if f.suffix == ".json"]
        data = json.loads(json_files[0].read_text())
        finding = data["findings"][0]
        assert finding["finding_id"].startswith("cf-soc2-CC6.1-")
        assert len(finding["finding_id"].split("-")[-1]) == 8

    def test_schema_version(
        self,
        exporter: GrcJsonExporter,
        sample_findings: list[dict[str, object]],
        metadata: dict[str, object],
        tmp_path: Path,
    ) -> None:
        result = exporter.export_to_file(sample_findings, metadata, tmp_path)
        json_files = [f for f in result.output_files if f.suffix == ".json"]
        data = json.loads(json_files[0].read_text())
        assert data["schema_version"] == 1

    def test_controls_evaluated(
        self,
        exporter: GrcJsonExporter,
        sample_findings: list[dict[str, object]],
        metadata: dict[str, object],
        tmp_path: Path,
    ) -> None:
        result = exporter.export_to_file(sample_findings, metadata, tmp_path)
        json_files = [f for f in result.output_files if f.suffix == ".json"]
        data = json.loads(json_files[0].read_text())
        assert "controls_evaluated" in data
        ctrl = data["controls_evaluated"][0]
        assert "framework" in ctrl
        assert "control_id" in ctrl
        assert "total_findings" in ctrl
        assert "pass_count" in ctrl
        assert "fail_count" in ctrl

    def test_metadata_fields(
        self,
        exporter: GrcJsonExporter,
        sample_findings: list[dict[str, object]],
        metadata: dict[str, object],
        tmp_path: Path,
    ) -> None:
        result = exporter.export_to_file(sample_findings, metadata, tmp_path)
        json_files = [f for f in result.output_files if f.suffix == ".json"]
        data = json.loads(json_files[0].read_text())
        assert "metadata" in data
        meta = data["metadata"]
        assert "scan_id" in meta
        assert "timestamp" in meta
        assert "cloud" in meta

    def test_companion_instructions(
        self,
        exporter: GrcJsonExporter,
        sample_findings: list[dict[str, object]],
        metadata: dict[str, object],
        tmp_path: Path,
    ) -> None:
        result = exporter.export_to_file(sample_findings, metadata, tmp_path)
        md_files = [f for f in result.output_files if f.suffix == ".md"]
        assert len(md_files) == 1
