"""Tests for complyform.core.greenfield.renderer — Jinja2 template engine."""

from __future__ import annotations

from typing import TYPE_CHECKING
from unittest.mock import patch

if TYPE_CHECKING:
    from pathlib import Path

import pytest

from complyform.core.errors import TemplateNotFoundError
from complyform.core.greenfield.renderer import GenerateContext, render_terraform
from complyform.core.greenfield.service_catalog import ServiceDefinition


def _make_service(
    id: str = "cloudsql",
    display_name: str = "Cloud SQL",
    category: str = "database",
    resource_types: list[str] | None = None,
) -> ServiceDefinition:
    return ServiceDefinition(
        id=id,
        display_name=display_name,
        category=category,
        resource_types=resource_types or ["google_sql_database_instance"],
        compliance_surface=["encryption_at_rest"],
        default_config={},
    )


def _make_context(
    cloud: str = "gcp",
    services: list[ServiceDefinition] | None = None,
    merged_configs: dict[str, dict[str, object]] | None = None,
    compliance_comments: dict[str, list[str]] | None = None,
) -> GenerateContext:
    return GenerateContext(
        project_id="test-project",
        cloud=cloud,
        org_id=None,
        region="us-central1",
        frameworks=["soc2"],
        services=services or [_make_service()],
        merged_configs=merged_configs or {},
        dependencies=[],
        compliance_comments=compliance_comments or {},
    )


class TestRenderGcpProviders:
    @patch("complyform.core.greenfield.renderer._run_fmt")
    def test_providers_has_google(self, mock_fmt: object, tmp_path: Path) -> None:
        ctx = _make_context()
        render_terraform(ctx, tmp_path)
        providers = (tmp_path / "providers.tf").read_text()
        assert "google" in providers
        assert "~> 6.0" in providers


class TestRenderVariables:
    @patch("complyform.core.greenfield.renderer._run_fmt")
    def test_variables_has_project_id(self, mock_fmt: object, tmp_path: Path) -> None:
        ctx = _make_context()
        render_terraform(ctx, tmp_path)
        variables = (tmp_path / "variables.tf").read_text()
        assert "project_id" in variables
        assert "region" in variables


class TestRenderBackendCommented:
    @patch("complyform.core.greenfield.renderer._run_fmt")
    def test_backend_commented(self, mock_fmt: object, tmp_path: Path) -> None:
        ctx = _make_context()
        render_terraform(ctx, tmp_path)
        backend = (tmp_path / "backend.tf").read_text()
        assert "#" in backend
        assert "gcs" in backend.lower() or "backend" in backend.lower()


class TestRenderMainTfComplianceComments:
    @patch("complyform.core.greenfield.renderer._run_fmt")
    def test_compliance_comments(self, mock_fmt: object, tmp_path: Path) -> None:
        ctx = _make_context(
            compliance_comments={
                "google_sql_database_instance": ["soc2.CC6.1", "hipaa.164.312"],
            },
        )
        render_terraform(ctx, tmp_path)
        main_tf = tmp_path / "main.tf"
        if main_tf.exists():
            content = main_tf.read_text()
            assert "Compliance" in content or "soc2" in content


class TestRenderReadme:
    @patch("complyform.core.greenfield.renderer._run_fmt")
    def test_readme_generated(self, mock_fmt: object, tmp_path: Path) -> None:
        ctx = _make_context()
        render_terraform(ctx, tmp_path)
        readme = (tmp_path / "README.md").read_text()
        assert "soc2" in readme
        assert "test-project" in readme


class TestRenderTfvarsExample:
    @patch("complyform.core.greenfield.renderer._run_fmt")
    def test_tfvars_generated(self, mock_fmt: object, tmp_path: Path) -> None:
        ctx = _make_context()
        render_terraform(ctx, tmp_path)
        tfvars = (tmp_path / "terraform.tfvars.example").read_text()
        assert "project_id" in tfvars
        assert "test-project" in tfvars


class TestTemplateNotFound:
    @patch("complyform.core.greenfield.renderer._run_fmt")
    def test_unknown_cloud(self, mock_fmt: object, tmp_path: Path) -> None:
        ctx = _make_context(cloud="nonexistent_cloud")
        with pytest.raises(TemplateNotFoundError):
            render_terraform(ctx, tmp_path)


class TestRenderCopiesInitYaml:
    """The init yaml copy is handled in generate_cmd, not renderer.

    This test verifies render_terraform returns the expected file list.
    """

    @patch("complyform.core.greenfield.renderer._run_fmt")
    def test_returns_file_list(self, mock_fmt: object, tmp_path: Path) -> None:
        ctx = _make_context()
        files = render_terraform(ctx, tmp_path)
        assert len(files) >= 5  # scaffolding + tfvars
        names = {f.name for f in files}
        assert "providers.tf" in names
        assert "variables.tf" in names
        assert "terraform.tfvars.example" in names
