"""
Storage backend factory.

Usage:
    from autopil.db import create_stores

    audit_log, key_store, tenant_store, policy_store, alert_store, lineage_store, session_store = create_stores(database_url="postgresql://...")
    audit_log, key_store, tenant_store, policy_store, alert_store, lineage_store, session_store = create_stores(db_path="/data/autopil.db")
"""

from .base import (
    AuditLogBase, AlertStoreBase, CatalogStoreBase, KeyStoreBase,
    LineageStoreBase, SessionStoreBase, TenantStoreBase, PolicyStoreBase,
    TrialStoreBase,
)


def create_stores(
    database_url: str | None = None,
    db_path: str = "autopil_audit.db",
) -> tuple[AuditLogBase, KeyStoreBase, TenantStoreBase, PolicyStoreBase, AlertStoreBase, LineageStoreBase, SessionStoreBase]:
    """
    Return (audit_log, key_store, tenant_store, policy_store, alert_store, lineage_store, session_store).

    - If database_url is set (postgresql://...) → Postgres backend
    - Otherwise → SQLite backend using db_path
    """
    if database_url:
        from .postgres import (PostgresAuditLog, PostgresKeyStore, PostgresTenantStore,
                                PostgresPolicyStore, PostgresAlertStore)
        from .sqlite import SQLiteLineageStore, SQLiteSessionStore
        return (
            PostgresAuditLog(database_url),
            PostgresKeyStore(database_url),
            PostgresTenantStore(database_url),
            PostgresPolicyStore(database_url),
            PostgresAlertStore(database_url),
            SQLiteLineageStore(db_path),   # lineage store always SQLite for now
            SQLiteSessionStore(db_path),   # session store always SQLite for now
        )

    from .sqlite import (SQLiteAuditLog, SQLiteKeyStore, SQLiteTenantStore,
                         SQLitePolicyStore, SQLiteAlertStore, SQLiteLineageStore,
                         SQLiteSessionStore)
    return (
        SQLiteAuditLog(db_path),
        SQLiteKeyStore(db_path),
        SQLiteTenantStore(db_path),
        SQLitePolicyStore(db_path),
        SQLiteAlertStore(db_path),
        SQLiteLineageStore(db_path),
        SQLiteSessionStore(db_path),
    )


def create_catalog_store(
    database_url: str | None = None,
    db_path: str = "autopil_audit.db",
) -> CatalogStoreBase:
    """
    Return a CatalogStoreBase implementation.

    - If database_url is set (postgresql://...) → PostgresCatalogStore
    - Otherwise → SQLiteCatalogStore using db_path
    """
    if database_url:
        from .postgres import PostgresCatalogStore
        return PostgresCatalogStore(database_url)
    from .sqlite import SQLiteCatalogStore
    return SQLiteCatalogStore(db_path)


def create_trial_store(
    database_url: str | None = None,
    db_path: str = "autopil_audit.db",
) -> TrialStoreBase:
    """Return a TrialStoreBase implementation."""
    if database_url:
        from .postgres import PostgresTrialStore
        return PostgresTrialStore(database_url)
    from .sqlite import SQLiteTrialStore
    return SQLiteTrialStore(db_path)


__all__ = [
    "create_stores", "create_catalog_store", "create_trial_store",
    "AuditLogBase", "AlertStoreBase", "CatalogStoreBase", "KeyStoreBase",
    "LineageStoreBase", "SessionStoreBase", "TenantStoreBase", "PolicyStoreBase",
    "TrialStoreBase", "PostgresCatalogStore",
]


def __getattr__(name: str):
    # Lazy import to avoid requiring psycopg2 when using SQLite-only deployments
    if name == "PostgresCatalogStore":
        from .postgres import PostgresCatalogStore
        return PostgresCatalogStore
    raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
