"""CLI integration tests for the assess command."""

from __future__ import annotations

import json
from datetime import UTC, datetime
from typing import TYPE_CHECKING
from unittest.mock import patch

if TYPE_CHECKING:
    from pathlib import Path

import pytest
from typer.testing import CliRunner

from complyform.cli.main import app
from complyform.core.scanner.state_parser import ResourceRecord

runner = CliRunner()


def _make_cached_scan(
    tmp_path: Path,
) -> Path:
    """Create a fake scan cache directory with valid metadata and inventory."""
    cache_dir = tmp_path / "cache"
    entry_dir = cache_dir / "abcdef0123456789"
    entry_dir.mkdir(parents=True)

    resource = ResourceRecord(
        address="module.test.google_compute_instance.main",
        resource_type="google_compute_instance",
        name="main",
        provider="google",
        attributes={"name": "test-vm", "machine_type": "e2-micro"},
        source_state="terraform.tfstate",
    )

    inventory = [resource.model_dump(mode="json")]
    (entry_dir / "inventory.json").write_text(json.dumps(inventory), encoding="utf-8")

    metadata = {
        "cache_version": 1,
        "state_hash": "sha256:abcdef0123456789",
        "state_path": "./terraform.tfstate",
        "cloud": "gcp",
        "scanned_at": datetime.now(UTC).isoformat(),
        "resource_count": 1,
        "complyform_version": "0.1.0",
    }
    (entry_dir / "metadata.json").write_text(json.dumps(metadata), encoding="utf-8")

    return cache_dir


class TestUnknownFramework:
    def test_nonexistent_framework_exits_nonzero(self) -> None:
        result = runner.invoke(
            app,
            ["assess", "--frameworks", "nonexistent"],
        )
        assert result.exit_code != 0


class TestCIFlagsTierGated:
    @pytest.mark.parametrize(
        "flag",
        ["--cross-validate", "--iam-analysis", "--estimate-cost"],
    )
    def test_ci_flag_tier_gated(self, flag: str, tmp_path: Path) -> None:
        """CI flags trigger tier enforcement, not future-release stub."""
        cache_dir = _make_cached_scan(tmp_path)
        with patch(
            "complyform.cli.assess_cmd.ScanCache",
            return_value=_patched_scan_cache(cache_dir),
        ):
            result = runner.invoke(
                app,
                ["assess", "--frameworks", "soc2", flag],
            )
        # Tier enforcement or credential error — not exit 0 with stub msg
        assert "Coming in a future release" not in (result.output or "")


class TestExplainFlag:
    def test_explain_flag_runs_with_assessment(self, tmp_path: Path) -> None:
        cache_dir = _make_cached_scan(tmp_path)
        with patch(
            "complyform.cli.assess_cmd.ScanCache",
            return_value=_patched_scan_cache(cache_dir),
        ):
            result = runner.invoke(
                app,
                ["assess", "--frameworks", "soc2", "--explain"],
            )
        # --explain now triggers inline explanations (exit 0 or compliance code)
        assert result.exit_code in (0, 1)


def _patched_scan_cache(cache_dir: Path) -> object:
    """Return a ScanCache-like object that uses the given cache_dir."""
    from complyform.core.cache import ScanCache

    return ScanCache(cache_dir=cache_dir)
