"""PC-02: ``pool_pre_ping`` overhead measurement (documentary).

`pool_pre_ping=True` (the default in `create_engine`) sends a
`SELECT 1` to the DB on every connection checkout. This catches
stale connections after a DB restart / firewall reset / pool-
recycle event — the retry happens transparently. The cost is
**one DB roundtrip per checkout**.

This test exists to **document** the cost on the maintainer's
local environment. It is intentionally NOT a pass/fail gate:

  - With SQLite (the only DB available in-process to this test
    suite), `pool_pre_ping` runs against an in-memory engine
    where the "roundtrip" is essentially free — the measurement
    shows the wrapper's own bookkeeping cost, not the real
    network-RTT cost a production Postgres deployment pays.
  - The real number for any given deployment depends on the
    consumer's DB host latency. The measurement template here
    is what operators run against THEIR DB if they want to
    decide whether to disable pre-ping.

The test prints the measurement (visible in pytest `-s` mode)
and asserts only that both engines built + a checkout completed
— the regression-detection target is the *creation/checkout
path*, not the latency number, because the latter is
deployment-dependent.

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 asyncio
import time

import pytest

from mgf.sqlalchemy import create_engine

_N_CHECKOUTS = 200


async def _measure_checkouts(*, pool_pre_ping: bool) -> tuple[float, int]:
    """Build an engine with `pool_pre_ping` set; drive N checkouts.

    Returns (total_seconds, successful_checkouts). The engine is
    SQLite in-memory — the cost measured here is the wrapper's
    bookkeeping path, not the real network-RTT a Postgres
    deployment pays.
    """
    engine = create_engine(
        "sqlite+aiosqlite:///:memory:",
        pool_pre_ping=pool_pre_ping,
    )
    try:
        # Warm-up — first checkout pays first-call setup costs.
        async with engine.connect():
            pass

        start = time.perf_counter()
        successful = 0
        for _ in range(_N_CHECKOUTS):
            async with engine.connect():
                successful += 1
        elapsed = time.perf_counter() - start
        return elapsed, successful
    finally:
        await engine.dispose()


@pytest.mark.perf
class TestPoolPrePingImpact:
    """Document the `pool_pre_ping` overhead on the maintainer's stack.

    Documentary — not a pass/fail latency gate (real cost is
    deployment-dependent). Asserts only that both engines work
    end-to-end and complete the checkout sequence.
    """

    def test_pre_ping_overhead_measurement(self) -> None:
        async def _go() -> tuple[tuple[float, int], tuple[float, int]]:
            with_pp = await _measure_checkouts(pool_pre_ping=True)
            without_pp = await _measure_checkouts(pool_pre_ping=False)
            return with_pp, without_pp

        (with_total, with_count), (without_total, without_count) = asyncio.run(_go())

        # Sanity — both paths complete all checkouts.
        assert with_count == _N_CHECKOUTS, (
            f"PC-02: pool_pre_ping=True path dropped checkouts: {with_count}/{_N_CHECKOUTS}"
        )
        assert without_count == _N_CHECKOUTS, (
            f"PC-02: pool_pre_ping=False path dropped checkouts: {without_count}/{_N_CHECKOUTS}"
        )

        # Documentary output — pytest -s shows this.
        with_us = (with_total / _N_CHECKOUTS) * 1_000_000
        without_us = (without_total / _N_CHECKOUTS) * 1_000_000
        delta_us = with_us - without_us
        # `print()` so this appears with `pytest -s` for ops-side review.
        print(
            f"\nPC-02 measurement (sqlite+aiosqlite in-memory, "
            f"N={_N_CHECKOUTS}):\n"
            f"  pool_pre_ping=True:   {with_us:>7.2f} µs/checkout\n"
            f"  pool_pre_ping=False:  {without_us:>7.2f} µs/checkout\n"
            f"  delta (ping cost):    {delta_us:>+7.2f} µs/checkout\n"
            f"  (Real Postgres deployments will see the delta dominated "
            f"by network RTT; this in-memory measurement only shows the "
            f"wrapper's own bookkeeping.)"
        )
