# utils/database.py
"""Database utilities for database operations.

This module provides utility functions and classes to interact with a database using SQLAlchemy. It includes:
- Creating a PostgreSQL database engine with connection pooling.
- Generating a session factory for creating sessions.

Note: This project uses PostgreSQL only. SQLite is not supported.
"""

import logging

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.pool import QueuePool

logger = logging.getLogger(__name__)


def get_db_engine(database_url: str):
    """Create a PostgreSQL database engine with connection pooling.

    Args:
        database_url (str): The PostgreSQL URL string to connect to the database.

    Returns:
        sqlalchemy.engine.Engine: A SQLAlchemy Engine instance configured for PostgreSQL.

    Raises:
        ValueError: If database_url is not a PostgreSQL URL.
    """
    if not database_url.startswith("postgresql"):
        raise ValueError(
            f"Unsupported database: {database_url.split(':')[0]}. "
            "Only PostgreSQL is supported."
        )

    engine = create_engine(
        database_url,
        poolclass=QueuePool,
        pool_size=10,
        max_overflow=20,
        pool_pre_ping=True,
        echo=False,
    )

    # Log URL without password
    safe_url = database_url.split("@")[0] + "@..." if "@" in database_url else database_url
    logger.info(f"Database engine created for: {safe_url}")
    return engine


def get_session_local(engine):
    """Create a session factory to generate database sessions.

    Args:
        engine (sqlalchemy.engine.Engine): The SQLAlchemy Engine instance created by `get_db_engine`.

    Returns:
        sqlalchemy.orm.sessionmaker: A session factory bound to the provided engine, suitable for creating database sessions.
    """
    return sessionmaker(autocommit=False, autoflush=False, bind=engine)
