from __future__ import annotations

from collections.abc import Generator
from contextlib import contextmanager

from sqlalchemy import create_engine
from sqlalchemy.engine import Engine
from sqlalchemy.orm import Session, sessionmaker

from app.config import get_settings

_settings = get_settings()

engine_default: Engine = create_engine(
    _settings.database_url,
    pool_pre_ping=True,
    pool_recycle=3600,
)
engine_cluster: Engine = create_engine(
    _settings.cluster_database_url,
    pool_pre_ping=True,
    pool_recycle=3600,
)

SessionLocalDefault = sessionmaker(bind=engine_default, autoflush=False, autocommit=False, expire_on_commit=False)
SessionLocalCluster = sessionmaker(bind=engine_cluster, autoflush=False, autocommit=False, expire_on_commit=False)


def get_db_default() -> Generator[Session, None, None]:
    db = SessionLocalDefault()
    try:
        yield db
    finally:
        db.close()


def get_db_cluster() -> Generator[Session, None, None]:
    db = SessionLocalCluster()
    try:
        yield db
    finally:
        db.close()


@contextmanager
def session_scope_default() -> Generator[Session, None, None]:
    session = SessionLocalDefault()
    try:
        yield session
        session.commit()
    except Exception:
        session.rollback()
        raise
    finally:
        session.close()


@contextmanager
def session_scope_cluster() -> Generator[Session, None, None]:
    session = SessionLocalCluster()
    try:
        yield session
        session.commit()
    except Exception:
        session.rollback()
        raise
    finally:
        session.close()
