"""The in-memory SQLite the account tests run on: the auth tables, nothing else, one engine.

A plain helper module, not a conftest: DFP's own account tests and the kit's conformance pack
both import it, and a pure test that never touches accounts never pays for it. `install()`
swaps `app.db.SessionLocal` for a factory on this engine (every account store looks the
factory up at call time, so the swap reaches the session loader, the directory, the audit
sink and the kit's store alike) and `reset()` recreates the tables between tests. Foreign
keys are enforced, as on Postgres, so a missing principal fails here too.
"""

from __future__ import annotations

from sqlalchemy import create_engine, event
from sqlalchemy.orm import sessionmaker
from sqlalchemy.pool import StaticPool

from app import db as appdb
from app.models import (
    Account,
    AccountCredential,
    AccountGrant,
    AccountPreference,
    AccountLevel,
    AccountMember,
    AccountToken,
    AuditLog,
    AuthSession,
    Base,
    Brand,
    ClientTodo,
    ClientUpload,
    DiscussionComment,
    DiscussionItem,
    EmailSend,
    FeaturePriority,
    Notification,
    OwnerItemState,
    Thread,
    ThreadAsk,
    ThreadRead,
    CommentAck,
    CommentFlag,
    QuoteRequest,
    QuoteSelection,
)

TABLES = [
    Account.__table__, AccountCredential.__table__, AccountLevel.__table__, AccountMember.__table__,
    AccountGrant.__table__, AuthSession.__table__, AccountToken.__table__, AuditLog.__table__,
    Brand.__table__, DiscussionItem.__table__, Thread.__table__, DiscussionComment.__table__, FeaturePriority.__table__,
    Notification.__table__, EmailSend.__table__, AccountPreference.__table__, ThreadRead.__table__, ThreadAsk.__table__, CommentAck.__table__, CommentFlag.__table__,
    QuoteSelection.__table__, QuoteRequest.__table__, ClientTodo.__table__, ClientUpload.__table__,
    OwnerItemState.__table__,
]

engine = create_engine("sqlite://", connect_args={"check_same_thread": False}, poolclass=StaticPool)


@event.listens_for(engine, "connect")
def _foreign_keys_on(dbapi_connection, _record):
    dbapi_connection.execute("PRAGMA foreign_keys=ON")


TestSessionLocal = sessionmaker(bind=engine, autoflush=False, expire_on_commit=False, future=True)
_original = appdb.SessionLocal


def install() -> None:
    appdb.SessionLocal = TestSessionLocal


def uninstall() -> None:
    appdb.SessionLocal = _original


def reset() -> None:
    Base.metadata.drop_all(engine, tables=TABLES)
    Base.metadata.create_all(engine, tables=TABLES)
