"""Tests for Microsoft Purview exporter."""

from __future__ import annotations

import csv
import io
import json
from typing import TYPE_CHECKING

import pytest

from complyform.core.generators.evidence_export.purview import PurviewExporter

if TYPE_CHECKING:
    from pathlib import Path


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


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


@pytest.fixture
def sample_findings() -> list[dict[str, object]]:
    return [
        {
            "control_id": "CC6.1",
            "framework": "soc2",
            "resource_address": "azurerm_storage_account.main",
            "resource_type": "azurerm_storage_account",
            "status": "FAIL",
            "severity": "HIGH",
            "finding": "Storage not encrypted",
            "remediation": "Enable encryption",
            "checkov_id": None,
            "native_ids": None,
            "cross_mappings": None,
            "confidence": "high",
        }
    ]


class TestPurviewExporter:
    def test_format_id(self, exporter: PurviewExporter) -> None:
        assert exporter.FORMAT_ID == "purview"
        assert exporter.TIER_FEATURE == "evidence_export_native"

    def test_csv_columns(
        self,
        exporter: PurviewExporter,
        sample_findings: list[dict[str, object]],
        metadata: dict[str, object],
        tmp_path: Path,
    ) -> None:
        result = exporter.export_to_file(sample_findings, metadata, tmp_path)
        csv_files = [f for f in result.output_files if f.suffix == ".csv"]
        assert len(csv_files) == 1
        reader = csv.reader(io.StringIO(csv_files[0].read_text()))
        headers = next(reader)
        assert "improvement_action_title" in headers
        assert "implementation_status" in headers
        assert "test_status" in headers
        assert "test_date" in headers
        assert "notes" in headers
        assert "evidence_file" in headers

    def test_status_values_fail(
        self,
        exporter: PurviewExporter,
        sample_findings: list[dict[str, object]],
        metadata: dict[str, object],
        tmp_path: Path,
    ) -> None:
        result = exporter.export_to_file(sample_findings, metadata, tmp_path)
        csv_files = [f for f in result.output_files if f.suffix == ".csv"]
        reader = csv.DictReader(io.StringIO(csv_files[0].read_text()))
        row = next(reader)
        assert row["implementation_status"] == "not_implemented"
        assert row["test_status"] == "failed"

    def test_status_values_pass(
        self,
        exporter: PurviewExporter,
        metadata: dict[str, object],
        tmp_path: Path,
    ) -> None:
        findings = [
            {
                "control_id": "CC6.1",
                "framework": "soc2",
                "resource_address": "azurerm_storage_account.main",
                "resource_type": "azurerm_storage_account",
                "status": "PASS",
                "severity": "HIGH",
                "finding": "",
                "remediation": "",
                "checkov_id": None,
                "native_ids": None,
                "cross_mappings": None,
                "confidence": "high",
            }
        ]
        result = exporter.export_to_file(findings, metadata, tmp_path)
        csv_files = [f for f in result.output_files if f.suffix == ".csv"]
        reader = csv.DictReader(io.StringIO(csv_files[0].read_text()))
        row = next(reader)
        assert row["implementation_status"] == "implemented"
        assert row["test_status"] == "passed"

    def test_evidence_json_generated(
        self,
        exporter: PurviewExporter,
        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"]
        assert len(json_files) == 1
        data = json.loads(json_files[0].read_text())
        assert "evidence" in data

    def test_companion_instructions(
        self,
        exporter: PurviewExporter,
        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
