"""Tests for batch remediate 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:
    """Create a test manifest with *n* projects."""
    projects = [
        BatchProject(
            label=f"proj-{i}",
            cloud="gcp",
            state=f"/tmp/state-{i}.tfstate",
        )
        for i in range(n)
    ]
    return BatchManifest(projects=projects)


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


def _failing_fn(proj: BatchProject) -> dict[str, Any]:
    if proj.label == "proj-1":
        msg = "simulated failure"
        raise RuntimeError(msg)
    return {"status": "success", "patches": 1}


class TestBatchRemediateSuccess:
    def test_batch_remediate_success(self, tmp_path: Path) -> None:
        """All 3 projects succeed."""
        manifest = _make_manifest(3)
        result = run_batch_operation(manifest, "remediate", _success_fn, tmp_path)

        assert result.total == 3
        assert result.succeeded == 3
        assert result.failed == 0
        assert result.skipped == 0
        assert len(result.results) == 3
        for entry in result.results:
            assert entry["status"] == "success"


class TestBatchRemediatePartialFailure:
    def test_batch_remediate_partial_failure(self, tmp_path: Path) -> None:
        """1 of 3 fails — others still complete."""
        manifest = _make_manifest(3)
        result = run_batch_operation(manifest, "remediate", _failing_fn, tmp_path)

        assert result.total == 3
        assert result.succeeded == 2
        assert result.failed == 1
        assert result.results[1]["status"] == "failed"
        assert "simulated failure" in result.results[1]["error"]


class TestBatchRemediateTierGate:
    def test_batch_remediate_tier_gate(self) -> None:
        """Pro user rejected — batch_remediate needs Agency."""
        from complyform.core.auth.tier_enforcement import (
            TierInfo,
            check_feature,
        )
        from complyform.core.errors import FeatureNotAvailableError

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


class TestBatchRemediateSummaryJson:
    def test_batch_remediate_summary_json(self, tmp_path: Path) -> None:
        """Summary JSON is written with correct schema."""
        manifest = _make_manifest(2)
        run_batch_operation(manifest, "remediate", _success_fn, tmp_path)

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

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