"""Utilities for CLI commands that need database access.

Provides decorators and helpers so that plugin CLI commands can interact
with the FastPluggy database without importing the full web stack at
module load time.
"""


import functools
from typing import Any, Callable


def with_db_session(fn: Callable[..., Any]) -> Callable[..., Any]:
    """Decorator that lazily creates a SQLAlchemy session and injects it as ``db``.

    Usage inside a Click command::

        @click.command()
        @with_db_session
        def my_command(db):
            user = db.query(UserModel).first()
            ...

    The ``DATABASE_URL`` environment variable must be set (same as the web
    app).  The database engine and ``SessionLocal`` are imported lazily
    inside the wrapper so that simply *loading* a CLI module does not pull
    in the full web stack.

    The session is committed on success and rolled back on exception,
    matching the semantics of ``session_scope()`` in
    ``fastpluggy.core.database``.
    """

    @functools.wraps(fn)
    def wrapper(*args: Any, **kwargs: Any) -> Any:
        from fastpluggy.core.database import SessionLocal

        db = SessionLocal()
        try:
            result = fn(*args, db=db, **kwargs)
            db.commit()
            return result
        except Exception:
            db.rollback()
            raise
        finally:
            db.close()

    return wrapper
