"""Tests for batch report command — Phase 20c."""

from __future__ import annotations

import json
from typing import TYPE_CHECKING, Any

import pytest

from complyform.core.batch.executor import run_batch_operation
from complyform.core.batch.manifest import BatchManifest, BatchProject

if TYPE_CHECKING:
    from pathlib import Path


def _make_manifest(n: int = 3) -> BatchManifest:
    projects = [
        BatchProject(
            label=f"proj-{i}",
            cloud="gcp",
            state=f"/tmp/state-{i}.tfstate",
        )
        for i in range(n)
    ]
    return BatchManifest(projects=projects)


def _html_report_fn(
    proj: BatchProject,
) -> dict[str, Any]:
    return {
        "status": "success",
        "output_dir": f"/tmp/{proj.label}",
        "format": "html",
    }


def _pdf_brand_fn(
    proj: BatchProject,
) -> dict[str, Any]:
    return {
        "status": "success",
        "output_dir": f"/tmp/{proj.label}",
        "format": "pdf",
        "brand_yaml": f"/brands/{proj.label}/brand.yaml",
    }


class TestBatchReportHtml:
    def test_batch_report_html(self, tmp_path: Path) -> None:
        """3 projects, all HTML reports succeed."""
        manifest = _make_manifest(3)
        result = run_batch_operation(manifest, "report", _html_report_fn, tmp_path)

        assert result.total == 3
        assert result.succeeded == 3
        assert result.failed == 0
        for entry in result.results:
            assert entry["status"] == "success"
            assert entry["format"] == "html"


class TestBatchReportPdfWithBrandDir:
    def test_batch_report_pdf_with_brand_dir(self, tmp_path: Path) -> None:
        """Per-project brand.yaml paths are recorded."""
        manifest = _make_manifest(2)
        result = run_batch_operation(manifest, "report", _pdf_brand_fn, tmp_path)

        assert result.total == 2
        assert result.succeeded == 2
        for entry in result.results:
            assert entry["format"] == "pdf"
            assert "brand.yaml" in entry["brand_yaml"]


class TestBatchReportTierGate:
    def test_batch_report_tier_gate(self) -> None:
        """batch_scan feature required — Community rejected."""
        from complyform.core.auth.tier_enforcement import (
            TierInfo,
            check_feature,
        )
        from complyform.core.errors import FeatureNotAvailableError

        tier_info = TierInfo(
            tier="community",
            assess_frameworks=[],
            remediate_frameworks=[],
            features=[],
            scan_sources=[],
            project_limit=None,
            batch_limit=None,
            discover_limit=None,
            expires_at=None,
        )
        with pytest.raises(FeatureNotAvailableError):
            check_feature("batch_scan", tier_info)


class TestBatchReportSummaryJson:
    def test_batch_report_summary_json(self, tmp_path: Path) -> None:
        """Summary JSON written with correct schema."""
        manifest = _make_manifest(2)
        run_batch_operation(manifest, "report", _html_report_fn, tmp_path)

        summary_path = tmp_path / "batch-report-summary.json"
        assert summary_path.exists()

        data = json.loads(summary_path.read_text(encoding="utf-8"))
        assert data["schema_version"] == 1
        assert data["operation"] == "report"
        assert data["total"] == 2
        assert data["succeeded"] == 2
        assert len(data["results"]) == 2
