"""Process-wide singleton async engine + session helper.

Previously every API blueprint lazily built its own engine via make_engine(),
so the process ran N connection pools. This module owns ONE engine for the
whole app; create_app() disposes it on shutdown via after_serving.
"""

from contextlib import asynccontextmanager

from sqlalchemy.ext.asyncio import (
    AsyncEngine,
    async_sessionmaker,
    create_async_engine,
)

from .config import get_config

_engine: AsyncEngine | None = None
_sessionmaker: async_sessionmaker | None = None


def get_engine() -> AsyncEngine:
    global _engine, _sessionmaker
    if _engine is None:
        _engine = create_async_engine(
            get_config().database_url, pool_pre_ping=True, future=True
        )
        _sessionmaker = async_sessionmaker(_engine, expire_on_commit=False)
    return _engine


def _get_sessionmaker() -> async_sessionmaker:
    if _sessionmaker is None:
        get_engine()
    assert _sessionmaker is not None
    return _sessionmaker


@asynccontextmanager
async def get_session():
    """`async with get_session() as session:` — one shared pool."""
    Session = _get_sessionmaker()
    async with Session() as session:
        yield session


async def dispose_engine() -> None:
    global _engine, _sessionmaker
    if _engine is not None:
        await _engine.dispose()
    _engine = None
    _sessionmaker = None
