"""
AFI conformance — same @client fixture, same schema, both adapters.

Gates that mizan-django and mizan-fastapi emit equivalent schemas for the
same registered functions. If this passes, the codegen produces equivalent
TypeScript output regardless of which backend the frontend is generated
against (codegen is deterministic over schema input).

This is a substrate-level gate, not e2e. It catches adapter symmetry
problems — Pydantic→OpenAPI converter divergence, metadata leakage,
ordering non-determinism — without running a real frontend or backend.
"""

from __future__ import annotations

import json
import os
import subprocess
import sys
from pathlib import Path

import pytest

HERE = Path(__file__).parent
DJANGO_MANAGE = HERE / "django_app" / "manage.py"


# ─── Schema fetchers ────────────────────────────────────────────────────────


def _fetch_django_schema() -> dict:
    """Spawn Django's management command and parse its stdout JSON."""
    result = subprocess.run(
        [sys.executable, str(DJANGO_MANAGE), "export_mizan_schema", "--indent", "0"],
        capture_output=True,
        text=True,
        check=False,
        env={**os.environ, "PYTHONDONTWRITEBYTECODE": "1"},
    )
    if result.returncode != 0:
        pytest.fail(f"export_mizan_schema failed:\nstdout:\n{result.stdout}\nstderr:\n{result.stderr}")
    return json.loads(result.stdout)


def _fetch_fastapi_schema() -> dict:
    """Build the FastAPI app inline (fresh registry) and call build_schema()."""
    sys.path.insert(0, str(HERE))
    try:
        from mizan_core.registry import clear_registry
        from mizan_fastapi import build_schema
        from fastapi_app import make_app

        clear_registry()
        make_app()
        return build_schema()
    finally:
        sys.path.remove(str(HERE))


# ─── Tests ──────────────────────────────────────────────────────────────────


@pytest.fixture(scope="module")
def schemas() -> tuple[dict, dict]:
    return _fetch_django_schema(), _fetch_fastapi_schema()


class AFISubsetTests:
    """The AFI surface — x-mizan-functions and x-mizan-contexts — must match."""

    def test_x_mizan_functions_match(self, schemas):
        from schema_normalizer import afi_subset
        django, fastapi = schemas
        assert afi_subset(django)["x-mizan-functions"] == afi_subset(fastapi)["x-mizan-functions"]

    def test_x_mizan_contexts_match(self, schemas):
        from schema_normalizer import afi_subset
        django, fastapi = schemas
        assert afi_subset(django)["x-mizan-contexts"] == afi_subset(fastapi)["x-mizan-contexts"]


class TypeSchemasTests:
    """Per-function Input/Output Pydantic→OpenAPI schemas — codegen feeds these to openapi-typescript."""

    def test_function_io_schemas_match(self, schemas):
        from schema_normalizer import function_io_schemas
        django, fastapi = schemas
        assert function_io_schemas(django) == function_io_schemas(fastapi)
