"""Shared pytest fixtures for the ``tests/`` tree.

Provides an ephemeral PostgreSQL engine for tests that exercise SQLModel
repositories. PostgreSQL has no true in-memory mode; ``pytest-postgresql``
starts a real, throwaway server in a temp directory (the process is started
once per session and a fresh database is created/dropped per test). That is
the closest equivalent to "in-memory" and matches production behaviour far
better than SQLite (enums, JSONB, constraint semantics, etc.).
"""

from __future__ import annotations

import glob
from collections.abc import Iterator
from typing import Any

import pytest
from psycopg import Connection
from pytest_postgresql import factories
from sqlalchemy import Engine
from sqlmodel import SQLModel, create_engine

# Importing the SQLModel row modules registers their tables on
# SQLModel.metadata so ``create_all`` builds the full schema. Imports look
# unused; they aren't.


# pg_ctl ships under a versioned path and is not on PATH in the dev container.
_PG_CTL = next(iter(sorted(glob.glob("/usr/lib/postgresql/*/bin/pg_ctl"))), "pg_ctl")

postgresql_proc = factories.postgresql_proc(
    executable=_PG_CTL
)  # pyright: ignore[reportUnknownMemberType]
postgresql = factories.postgresql("postgresql_proc")


@pytest.fixture
def db_engine(postgresql: Connection[Any]) -> Iterator[Engine]:
    """A SQLModel engine bound to a fresh, ephemeral PostgreSQL database."""
    info = postgresql.info
    url = f"postgresql+psycopg://{info.user}:@{info.host}:{info.port}/{info.dbname}"
    engine = create_engine(url)
    SQLModel.metadata.create_all(engine)
    try:
        yield engine
    finally:
        SQLModel.metadata.drop_all(engine)
        engine.dispose()
