# app/core/database.py
"""
Database configuration and session management.

This module provides classes and functions for:
- Database engine creation and configuration
- Session management with connection pooling
- Database dependency for FastAPI routes
"""

import logging

from sqlalchemy import create_engine, event
from sqlalchemy.orm import declarative_base, sessionmaker

from .config import settings


def _configure_sqlite_connection(dbapi_connection, connection_record):
    """Configure SQLite connection for better concurrency.

    - WAL mode: Allows concurrent reads during writes
    - busy_timeout: Wait up to 30 seconds if database is locked
    - synchronous=NORMAL: Balance between safety and performance
    """
    cursor = dbapi_connection.cursor()
    cursor.execute("PRAGMA journal_mode=WAL")
    cursor.execute("PRAGMA busy_timeout=30000")
    cursor.execute("PRAGMA synchronous=NORMAL")
    cursor.close()


# Create engine with SQLite-specific configuration
engine_kwargs = {}

# Add SQLite-specific settings for better concurrent access
if settings.database_url.startswith("sqlite"):
    engine_kwargs["connect_args"] = {"check_same_thread": False}

engine = create_engine(settings.database_url, **engine_kwargs)

# Configure SQLite pragmas on connection
if settings.database_url.startswith("sqlite"):
    event.listen(engine, "connect", _configure_sqlite_connection)

SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)

Base = declarative_base()

logger = logging.getLogger(__name__)


def get_db():
    """
    Database session dependency for FastAPI routes.

    Yields a database session and ensures proper cleanup.
    Handles exceptions and rolls back transactions on error.
    """
    db = SessionLocal()
    try:
        yield db
    except Exception as e:
        logger.error(f"Database session error: {e}")
        db.rollback()
        raise
    finally:
        db.close()
