"""Tests for security document templates (Module 3)."""

import pytest
from unittest.mock import MagicMock, patch
from fastapi.testclient import TestClient
from fastapi import FastAPI
from datetime import datetime

from compliance.api.legal_template_routes import router
from classroom_engine.database import get_db
from compliance.api.tenant_utils import get_tenant_id

DEFAULT_TENANT_ID = "9282a473-5c95-4b3a-bf78-0ecc0ec71d3e"

# =============================================================================
# Test App Setup
# =============================================================================

app = FastAPI()
app.include_router(router)

mock_db = MagicMock()


def override_get_db():
    yield mock_db


def override_tenant():
    return DEFAULT_TENANT_ID


app.dependency_overrides[get_db] = override_get_db
app.dependency_overrides[get_tenant_id] = override_tenant

client = TestClient(app)

SECURITY_TEMPLATE_TYPES = [
    "it_security_concept",
    "data_protection_concept",
    "backup_recovery_concept",
    "logging_concept",
    "incident_response_plan",
    "access_control_concept",
    "risk_management_concept",
]


# =============================================================================
# Helpers
# =============================================================================

def make_template_row(doc_type, title="Test Template", content="# Test"):
    row = MagicMock()
    row._mapping = {
        "id": "tmpl-001",
        "tenant_id": DEFAULT_TENANT_ID,
        "document_type": doc_type,
        "title": title,
        "description": f"Test {doc_type}",
        "content": content,
        "placeholders": ["COMPANY_NAME", "ISB_NAME"],
        "language": "de",
        "jurisdiction": "DE",
        "status": "published",
        "license_id": None,
        "license_name": None,
        "source_name": None,
        "inspiration_sources": [],
        "created_at": datetime(2026, 3, 14),
        "updated_at": datetime(2026, 3, 14),
    }
    return row


# =============================================================================
# Tests
# =============================================================================

class TestSecurityTemplateTypes:
    """Verify the 7 security template types are accepted by the API."""

    def test_all_security_types_in_valid_set(self):
        """All 7 security template types are in VALID_DOCUMENT_TYPES."""
        from compliance.api.legal_template_routes import VALID_DOCUMENT_TYPES

        for doc_type in SECURITY_TEMPLATE_TYPES:
            assert doc_type in VALID_DOCUMENT_TYPES, (
                f"{doc_type} not in VALID_DOCUMENT_TYPES"
            )

    def test_security_template_count(self):
        """There are exactly 7 security template types."""
        assert len(SECURITY_TEMPLATE_TYPES) == 7

    def test_create_security_template_accepted(self):
        """Creating a template with a security type is accepted (not 400)."""
        insert_row = MagicMock()
        insert_row._mapping = {
            "id": "new-tmpl",
            "tenant_id": DEFAULT_TENANT_ID,
            "document_type": "it_security_concept",
            "title": "IT-Sicherheitskonzept",
            "description": "Test",
            "content": "# IT-Sicherheitskonzept",
            "placeholders": [],
            "language": "de",
            "jurisdiction": "DE",
            "status": "draft",
            "license_id": None,
            "license_name": None,
            "source_name": None,
            "inspiration_sources": [],
            "created_at": datetime(2026, 3, 14),
            "updated_at": datetime(2026, 3, 14),
        }
        mock_db.execute.return_value.fetchone.return_value = insert_row
        mock_db.commit = MagicMock()

        resp = client.post("/legal-templates", json={
            "document_type": "it_security_concept",
            "title": "IT-Sicherheitskonzept",
            "content": "# IT-Sicherheitskonzept\n\n## 1. Managementzusammenfassung",
            "language": "de",
            "jurisdiction": "DE",
        })
        # Should NOT be 400 (invalid type)
        assert resp.status_code != 400 or "Invalid document_type" not in resp.text

    def test_invalid_type_rejected(self):
        """A non-existent template type is rejected with 400."""
        resp = client.post("/legal-templates", json={
            "document_type": "nonexistent_type",
            "title": "Test",
            "content": "# Test",
        })
        assert resp.status_code == 400
        assert "Invalid document_type" in resp.json()["detail"]


class TestSecurityTemplateFilter:
    """Verify filtering templates by security document types."""

    def test_filter_by_security_type(self):
        """GET /legal-templates?document_type=it_security_concept returns matching templates."""
        row = make_template_row("it_security_concept", "IT-Sicherheitskonzept")
        mock_db.execute.return_value.fetchall.return_value = [row]

        resp = client.get("/legal-templates?document_type=it_security_concept")
        assert resp.status_code == 200
        data = resp.json()
        assert "templates" in data or isinstance(data, list)


class TestSecurityTemplatePlaceholders:
    """Verify placeholder structure for security templates."""

    def test_common_placeholders_present(self):
        """Security templates should use standard placeholders."""
        common_placeholders = [
            "COMPANY_NAME", "GF_NAME", "ISB_NAME",
            "DOCUMENT_VERSION", "VERSION_DATE", "NEXT_REVIEW_DATE",
        ]
        row = make_template_row(
            "it_security_concept",
            content="# IT-Sicherheitskonzept\n{{COMPANY_NAME}} {{ISB_NAME}}"
        )
        row._mapping["placeholders"] = common_placeholders
        mock_db.execute.return_value.fetchone.return_value = row

        # Verify the mock has all expected placeholders
        assert all(
            p in row._mapping["placeholders"]
            for p in ["COMPANY_NAME", "GF_NAME", "ISB_NAME"]
        )
