"""Tests for cli/report_cmd.py — HTML format routing and tier gating."""

from __future__ import annotations

from datetime import UTC, datetime
from typing import TYPE_CHECKING, Any
from unittest.mock import MagicMock, patch

if TYPE_CHECKING:
    from pathlib import Path

import pytest

from complyform.core.assessor.control_matcher import Finding
from complyform.core.auth.tier_enforcement import TierInfo
from complyform.core.errors import FeatureNotAvailableError, NoCachedAssessmentError


def _tier_info(tier: str = "pro", features: list[str] | None = None) -> TierInfo:
    return TierInfo(
        tier=tier,
        assess_frameworks=["all"],
        remediate_frameworks=["soc2"],
        features=features or (["html_report"] if tier != "community" else []),
        scan_sources=["local_state"],
        project_limit=1,
        batch_limit=10,
        discover_limit=50,
        expires_at=None,
    )


def _finding(**overrides: Any) -> Finding:
    defaults: dict[str, Any] = {
        "control_id": "CC6.1",
        "framework": "soc2",
        "resource_address": "google_sql.main",
        "resource_type": "google_sql_database_instance",
        "status": "FAIL",
        "severity": "HIGH",
        "finding": "SSL not enforced",
        "remediation": "Enable SSL",
        "checkov_id": "CKV_GCP_6",
        "cross_mappings": None,
        "native_ids": None,
        "confidence": "verified",
    }
    defaults.update(overrides)
    return Finding(**defaults)


class TestReportCmdHTML:
    """Tests for HTML report command integration."""

    def test_community_blocked(self) -> None:
        """Community tier + --format=html raises FeatureNotAvailableError."""
        from complyform.core.auth.tier_enforcement import check_feature

        ti = _tier_info("community")
        with pytest.raises(FeatureNotAvailableError) as exc_info:
            check_feature("html_report", ti)
        assert exc_info.value.error_code == 24

    def test_pro_allowed(self) -> None:
        """Pro tier: check_feature does not raise for html_report."""
        from complyform.core.auth.tier_enforcement import check_feature

        ti = _tier_info("pro")
        # Should not raise
        check_feature("html_report", ti)

    def test_team_allowed(self) -> None:
        """Team tier: check_feature does not raise."""
        from complyform.core.auth.tier_enforcement import check_feature

        ti = _tier_info("team", features=["html_report"])
        check_feature("html_report", ti)

    @patch("complyform.core.cache.ScanCache.latest", return_value=None)
    @patch(
        "complyform.core.auth.license.LicenseManager.resolve_tier_info",
    )
    def test_no_cached_assessment(
        self,
        mock_resolve: MagicMock,
        mock_latest: MagicMock,
    ) -> None:
        """No cache: raises NoCachedAssessmentError."""
        mock_resolve.return_value = _tier_info("pro")

        from complyform.cli.report_cmd import _generate_html_report

        app_ctx = MagicMock()
        with pytest.raises(NoCachedAssessmentError):
            _generate_html_report(
                app_ctx, frameworks=None, severity=None, output_dir=None
            )

    def test_output_filename_pattern(self, tmp_path: Path) -> None:
        """Output file matches complyform-report-{date}-{frameworks}.html."""
        from complyform.reporting.html_report import render_html_report
        from complyform.reporting.report_data import (
            CrossMappingSection,
            ReportData,
            ReportMetadata,
            ReportSummary,
        )

        rd = ReportData(
            metadata=ReportMetadata(
                tool_version="0.1.0",
                generated_at="2026-03-16T00:00:00",
                cloud="gcp",
                scan_source="state",
                state_hash=None,
                frameworks=["soc2"],
                tier="pro",
                project_id=None,
            ),
            summary=ReportSummary(
                total_controls=0,
                passed=0,
                failed=0,
                manual_review=0,
                not_assessed=0,
                score=100.0,
                severity_counts={"critical": 0, "high": 0, "medium": 0, "low": 0},
                resource_count=0,
                assessment_duration_ms=0,
            ),
            findings=[],
            not_assessed_groups=[],
            cross_mappings=CrossMappingSection(
                total_shared=0, by_category={}, overlap_matrix=None
            ),
            cost_impact=None,
            cross_validation=None,
            frameworks_detail=[],
            upgrade_cta=None,
        )

        html = render_html_report(rd)
        today = datetime.now(UTC).strftime("%Y-%m-%d")
        filename = f"complyform-report-{today}-soc2.html"
        filepath = tmp_path / filename
        filepath.write_text(html, encoding="utf-8")

        assert filepath.exists()
        assert filepath.name.startswith("complyform-report-")
        assert filepath.name.endswith("-soc2.html")

    def test_custom_output_dir(self, tmp_path: Path) -> None:
        """File written to custom directory."""
        custom_dir = tmp_path / "custom"
        custom_dir.mkdir()

        from complyform.reporting.html_report import render_html_report
        from complyform.reporting.report_data import (
            CrossMappingSection,
            ReportData,
            ReportMetadata,
            ReportSummary,
        )

        rd = ReportData(
            metadata=ReportMetadata(
                tool_version="0.1.0",
                generated_at="2026-03-16T00:00:00",
                cloud="gcp",
                scan_source="state",
                state_hash=None,
                frameworks=["soc2"],
                tier="pro",
                project_id=None,
            ),
            summary=ReportSummary(
                total_controls=0,
                passed=0,
                failed=0,
                manual_review=0,
                not_assessed=0,
                score=100.0,
                severity_counts={"critical": 0, "high": 0, "medium": 0, "low": 0},
                resource_count=0,
                assessment_duration_ms=0,
            ),
            findings=[],
            not_assessed_groups=[],
            cross_mappings=CrossMappingSection(
                total_shared=0, by_category={}, overlap_matrix=None
            ),
            cost_impact=None,
            cross_validation=None,
            frameworks_detail=[],
            upgrade_cta=None,
        )

        html = render_html_report(rd)
        filepath = custom_dir / "complyform-report-2026-03-16-soc2.html"
        filepath.write_text(html, encoding="utf-8")

        assert filepath.exists()
        assert filepath.parent == custom_dir

    def test_framework_filter(self) -> None:
        """--frameworks=soc2 with multi-framework findings: only SOC2."""
        findings = [
            _finding(framework="soc2", control_id="CC6.1"),
            _finding(framework="hipaa", control_id="164.312"),
        ]
        filtered = [f for f in findings if f.framework == "soc2"]
        assert len(filtered) == 1
        assert filtered[0].framework == "soc2"

    def test_severity_filter(self) -> None:
        """--severity=critical: only CRITICAL findings."""
        findings = [
            _finding(severity="CRITICAL", control_id="C1"),
            _finding(severity="HIGH", control_id="C2"),
            _finding(severity="LOW", control_id="C3"),
        ]
        sev_order = ["CRITICAL", "HIGH", "MEDIUM", "LOW"]
        min_idx = sev_order.index("CRITICAL")
        allowed = set(sev_order[: min_idx + 1])
        filtered = [f for f in findings if f.severity in allowed]
        assert len(filtered) == 1
        assert filtered[0].severity == "CRITICAL"
