"""PC-01: per-call Python overhead of ``configure_env``.

``configure_env`` does cheap dispatch work before handing off to
alembic: an offline-mode check, a URL-prefix scan for async drivers,
optional naming-convention apply, and a call into one of three
``_run_*`` paths. None of it is per-row hot, but pinning the budget
catches regressions where dispatch somehow grows expensive.

Local baseline (Linux 6.17, Python 3.12, v0.2.0): ~5 µs/call across
both dispatch shapes. Budget is set at 100 µs/call — a ~20x cushion
so CI noise + slower hardware don't false-positive.

Marker: ``perf`` (registered in pyproject.toml). Excluded from the
default suite; run via ``pytest -m perf`` for the nightly sweep.
"""

from __future__ import annotations

import time
from unittest.mock import patch

import pytest
from sqlalchemy import MetaData

from mgf.alembic._env import configure_env

# Generous budget: measured ~5 µs locally; 100 µs accommodates CI
# noise + slower hardware + interpreter-version drift. A breach
# means the dispatch logic grew a per-call cost — investigate
# `configure_env` in `src/mgf/alembic/_env.py`.
_PER_CALL_BUDGET_US = 100.0


@pytest.mark.perf
class TestConfigureEnvOverhead:
    """Pin the per-call Python overhead of ``configure_env``."""

    def test_offline_dispatch_under_budget(self) -> None:
        """Offline path: ``is_offline_mode`` short-circuits to ``_run_offline``."""
        md = MetaData()

        with (
            patch("alembic.context.is_offline_mode", return_value=True),
            patch("mgf.alembic._env._run_offline"),
        ):
            # Warm-up — pay the first-call import / cache costs
            # before the measurement window opens.
            for _ in range(100):
                configure_env(database_url="sqlite:///x", target_metadata=md)

            n = 1000
            start = time.perf_counter()
            for _ in range(n):
                configure_env(database_url="sqlite:///x", target_metadata=md)
            elapsed = time.perf_counter() - start
            per_call_us = (elapsed / n) * 1_000_000

        assert per_call_us < _PER_CALL_BUDGET_US, (
            f"PC-01: configure_env offline-dispatch budget breach: "
            f"{per_call_us:.2f} µs/call (budget {_PER_CALL_BUDGET_US:.0f} µs). "
            f"Investigate dispatch logic in "
            f"src/mgf/alembic/_env.py::configure_env."
        )

    def test_online_sync_dispatch_under_budget(self) -> None:
        """Online sync path: non-async URL prefix → ``_run_online_sync``."""
        md = MetaData()

        with (
            patch("alembic.context.is_offline_mode", return_value=False),
            patch("mgf.alembic._env._run_online_sync"),
        ):
            for _ in range(100):
                configure_env(database_url="sqlite:///x", target_metadata=md)

            n = 1000
            start = time.perf_counter()
            for _ in range(n):
                configure_env(database_url="sqlite:///x", target_metadata=md)
            elapsed = time.perf_counter() - start
            per_call_us = (elapsed / n) * 1_000_000

        assert per_call_us < _PER_CALL_BUDGET_US, (
            f"PC-01: configure_env online-sync-dispatch budget breach: "
            f"{per_call_us:.2f} µs/call (budget {_PER_CALL_BUDGET_US:.0f} µs). "
            f"Investigate URL-prefix detection + dispatch in "
            f"src/mgf/alembic/_env.py::configure_env."
        )

    def test_naming_convention_apply_under_budget(self) -> None:
        """With a naming_convention dict: a small extra cost on each call."""
        md = MetaData()
        nc = {
            "ix": "ix_%(column_0_label)s",
            "uq": "uq_%(table_name)s_%(column_0_name)s",
            "ck": "ck_%(table_name)s_%(constraint_name)s",
            "fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s",
            "pk": "pk_%(table_name)s",
        }

        with (
            patch("alembic.context.is_offline_mode", return_value=True),
            patch("mgf.alembic._env._run_offline"),
        ):
            for _ in range(100):
                configure_env(
                    database_url="sqlite:///x",
                    target_metadata=md,
                    naming_convention=nc,
                )

            n = 1000
            start = time.perf_counter()
            for _ in range(n):
                configure_env(
                    database_url="sqlite:///x",
                    target_metadata=md,
                    naming_convention=nc,
                )
            elapsed = time.perf_counter() - start
            per_call_us = (elapsed / n) * 1_000_000

        assert per_call_us < _PER_CALL_BUDGET_US, (
            f"PC-01: configure_env naming-convention-apply budget breach: "
            f"{per_call_us:.2f} µs/call (budget {_PER_CALL_BUDGET_US:.0f} µs). "
            f"Investigate the naming-convention apply path in "
            f"src/mgf/alembic/_env.py::configure_env."
        )
