"""
AFI conformance — same fixture, same Mizan IR (KDL), all three adapters.

Gates that mizan-django, mizan-fastapi, and the Rust mizan-axum backend
emit byte-equivalent KDL for the same registered functions. The IR is the
contract; whatever language wrote the backend, the wire/codegen-facing
artifact is identical.

Substrate-level gate, not e2e. Catches adapter symmetry problems —
type-introspection divergence, ordering non-determinism — across all
backends in one place.
"""

from __future__ import annotations

import os
import subprocess
import sys
from pathlib import Path

import pytest


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


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


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

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


def _fetch_rust_ir() -> str:
    """Spawn the Rust `export-ir` bin and capture stdout."""
    result = subprocess.run(
        [
            "cargo", "run",
            "--quiet", "--release",
            "--manifest-path", str(RUST_APP_DIR / "Cargo.toml"),
            "--bin", "export-ir",
        ],
        capture_output=True,
        text=True,
        check=False,
    )
    if result.returncode != 0:
        pytest.fail(
            f"Rust export-ir failed:\nstdout:\n{result.stdout}\nstderr:\n{result.stderr}",
        )
    return result.stdout


@pytest.fixture(scope="module")
def fastapi_ir() -> str:
    return _fetch_fastapi_ir()


@pytest.fixture(scope="module")
def rust_ir() -> str:
    return _fetch_rust_ir()


@pytest.fixture(scope="module")
def django_ir() -> str:
    return _fetch_django_ir()


def test_fastapi_matches_rust(fastapi_ir: str, rust_ir: str) -> None:
    """FastAPI ≡ Rust. The Mizan IR is the contract across languages."""
    assert fastapi_ir == rust_ir, (
        "FastAPI and Rust emit divergent Mizan IR for the same registered "
        "functions. Substrate gate is red."
    )


def test_django_matches_fastapi(django_ir: str, fastapi_ir: str) -> None:
    """Django ≡ FastAPI."""
    assert django_ir == fastapi_ir, (
        "Django and FastAPI emit divergent Mizan IR for the same "
        "registered functions. Substrate gate is red."
    )


def test_all_three_match(django_ir: str, fastapi_ir: str, rust_ir: str) -> None:
    """All three backends emit byte-identical KDL."""
    assert django_ir == fastapi_ir == rust_ir, (
        "Three-way IR divergence — see test_django_matches_fastapi and "
        "test_fastapi_matches_rust for which pair drifts."
    )
