"""Shared test fixtures.

Every test gets a fresh in-memory SQLite database so tests are
isolated, fast, and leave no artifacts on disk.
"""

import pytest
import pytest_asyncio
from sqlmodel import Session
from sqlmodel import SQLModel
from sqlmodel import create_engine
from sqlmodel.pool import StaticPool

from transcription.config import Settings
from transcription.config import get_settings
from transcription.db.operations import create_all
from transcription.db.runtime import dispose_database_runtime
from transcription.db.runtime import get_engine
from transcription.db.runtime import get_session
from transcription.db.runtime import get_session_factory
from transcription.services.documents import DocumentService
from transcription.services.jobs import JobService


@pytest.fixture
def session():
    """Provide a clean synchronous database session for sync tests."""
    engine = create_engine(
        "sqlite://",
        connect_args={"check_same_thread": False},
        poolclass=StaticPool,
    )
    SQLModel.metadata.create_all(engine)
    with Session(engine) as sync_session:
        yield sync_session


@pytest_asyncio.fixture
async def default_settings():
    """Provide default settings for tests."""
    settings = get_settings(database_url="sqlite:///:memory:")
    await create_all(engine=get_engine(settings=settings))
    return settings


@pytest_asyncio.fixture
async def async_session(default_settings: Settings):
    """Provide a clean asynchronous database session for async tests."""
    async with get_session(settings=default_settings) as async_session:
        yield async_session

    await dispose_database_runtime()


@pytest.fixture
def default_session_factory(default_settings: Settings):
    """Provide a base fixture for tests that require database access."""
    session_factory = get_session_factory(settings=default_settings)
    return session_factory


@pytest.fixture
def job_service(default_session_factory) -> JobService:
    """Provide a JobService instance for testing."""
    return JobService(session_factory=default_session_factory)


@pytest.fixture
def document_service(default_session_factory) -> DocumentService:
    """Provide a DocumentService instance for testing."""
    return DocumentService(session_factory=default_session_factory)
