# ruff: noqa: I001

"""
Integration tests for PostgreSQL database module
Tests all functionality without requiring actual database connection

Auto-generated by RapidKit - Database PostgreSQL Module
"""

from importlib import import_module
from importlib import util as importlib_util
import inspect
from unittest.mock import AsyncMock

import pytest


SQLALCHEMY_AVAILABLE = importlib_util.find_spec("sqlalchemy") is not None
FASTAPI_AVAILABLE = importlib_util.find_spec("fastapi") is not None
try:
    SETTINGS_AVAILABLE = (
        importlib_util.find_spec("src.modules.free.essentials.settings.settings") is not None
    )
except ModuleNotFoundError:
    SETTINGS_AVAILABLE = False

pytestmark = [
    pytest.mark.integration,
    pytest.mark.template_integration,
    pytest.mark.skipif(
        not SQLALCHEMY_AVAILABLE,
        reason="SQLAlchemy not installed",
    ),
]


def test_imports():
    """Test that all essential imports work"""
    module = import_module("src.modules.free.database.db_postgres.postgres")
    expected_symbols = {
        "Base",
        "get_postgres_db",
        "get_sync_db",
        "check_postgres_connection",
        "check_postgres_connection_sync",
        "AsyncSessionLocal",
        "SyncSessionLocal",
        "transactional_async",
        "transactional_sync",
        "get_pool_status",
        "initialize_database",
        "close_async_engine",
        "close_sync_engine",
        "execute_raw_sql",
        "get_database_url",
        "async_engine",
        "sync_engine",
    }

    missing = [name for name in expected_symbols if not hasattr(module, name)]
    assert not missing, f"Missing expected exports: {missing}"


def test_engine_configuration():
    """Test that engines are properly configured"""
    from src.modules.free.database.db_postgres.postgres import async_engine, sync_engine

    assert async_engine is not None
    assert sync_engine is not None

    # Check async engine URL contains asyncpg driver
    async_url = str(async_engine.url)
    assert "postgresql+asyncpg://" in async_url or "postgresql://" in async_url

    # Check sync engine URL contains psycopg driver
    sync_url = str(sync_engine.url)
    assert "postgresql+psycopg://" in sync_url or "postgresql://" in sync_url


def test_session_makers():
    """Test that session makers are configured"""
    from src.modules.free.database.db_postgres.postgres import AsyncSessionLocal, SyncSessionLocal

    assert AsyncSessionLocal is not None
    assert SyncSessionLocal is not None


def test_dependency_injection_signature():
    """Test that FastAPI dependency has correct signature"""
    from src.modules.free.database.db_postgres.postgres import get_postgres_db, get_sync_db

    # Check async dependency
    assert inspect.isasyncgenfunction(get_postgres_db)

    # Check sync dependency
    assert inspect.isgeneratorfunction(get_sync_db)


def test_context_managers_signature():
    """Test that context managers have correct signatures"""
    from src.modules.free.database.db_postgres.postgres import transactional_async, transactional_sync

    # Context managers are decorated with @asynccontextmanager and @contextmanager
    assert callable(transactional_async)
    assert callable(transactional_sync)


@pytest.mark.asyncio
async def test_health_check_signature():
    """Test that health check functions have correct signatures"""
    from src.modules.free.database.db_postgres.postgres import (
    check_postgres_connection,
    check_postgres_connection_sync,
    get_pool_status,
    )

    assert inspect.iscoroutinefunction(check_postgres_connection)
    assert not inspect.iscoroutinefunction(check_postgres_connection_sync)
    assert inspect.iscoroutinefunction(get_pool_status)


def test_lifecycle_functions_signature():
    """Test that lifecycle functions have correct signatures"""
    from src.modules.free.database.db_postgres.postgres import (
    close_async_engine,
    close_sync_engine,
    initialize_database,
    )

    assert inspect.iscoroutinefunction(close_async_engine)
    assert not inspect.iscoroutinefunction(close_sync_engine)
    assert inspect.iscoroutinefunction(initialize_database)


def test_utility_functions():
    """Test utility functions"""
    from src.modules.free.database.db_postgres.postgres import get_database_url

    # Test without password hiding
    url = get_database_url(hide_password=False)
    assert isinstance(url, str)
    assert "postgresql://" in url

    # Test with password hiding
    url_masked = get_database_url(hide_password=True)
    assert isinstance(url_masked, str)
    assert "***" in url_masked or url_masked == url  # masked or no password


def test_settings_integration():
    """Test that settings are properly integrated"""
    if not SETTINGS_AVAILABLE:
        pytest.skip("Settings module not installed")

    settings_module = import_module("src.modules.free.essentials.settings.settings")
    settings = getattr(settings_module, "settings", None)
    if settings is None:
        pytest.skip("Settings settings object not available")

    assert hasattr(settings, "DATABASE_URL")
    assert hasattr(settings, "DB_POOL_SIZE")
    assert hasattr(settings, "DB_MAX_OVERFLOW")
    assert hasattr(settings, "DB_POOL_RECYCLE")
    assert hasattr(settings, "DB_POOL_TIMEOUT")
    assert hasattr(settings, "DB_ECHO")


def test_logging_integration():
    """Test that logging is properly integrated"""
    from src.modules.free.database.db_postgres.postgres import logger

    assert logger is not None
    assert hasattr(logger, "info")
    assert hasattr(logger, "error")
    assert hasattr(logger, "warning")


@pytest.mark.asyncio
async def test_async_session_context():
    """Test async session context manager"""
    from src.modules.free.database.db_postgres.postgres import get_postgres_db

    # This will fail without actual database, but tests the generator works
    gen = get_postgres_db()
    assert gen is not None


def test_sync_session_context():
    """Test sync session context manager"""
    from src.modules.free.database.db_postgres.postgres import get_sync_db

    # This will fail without actual database, but tests the generator works
    gen = get_sync_db()
    assert gen is not None


@pytest.mark.skipif(not FASTAPI_AVAILABLE, reason="FastAPI not installed")
def test_fastapi_health_endpoint(monkeypatch):
    """Test that the FastAPI health route responds with expected payload."""
    from fastapi import FastAPI, status
    from fastapi.testclient import TestClient

    from src.health import postgres as postgres_health

    # The project-level `src.health.postgres` is a shim that delegates to the
    # vendored health runtime. Patch the vendor module that actually defines the
    # route handler.
    vendor_health = postgres_health._load_vendor_module()  # type: ignore[attr-defined]

    monkeypatch.setattr(
        vendor_health,
        "check_postgres_connection",
        AsyncMock(return_value=None),
    )
    monkeypatch.setattr(
        vendor_health,
        "get_pool_status",
        AsyncMock(return_value={"size": 5, "overflow": 0}),
    )

    def _fake_database_url(*, hide_password: bool = True) -> str:
        return "postgresql://masked"

    monkeypatch.setattr(vendor_health, "get_database_url", _fake_database_url)

    app = FastAPI()
    postgres_health.register_postgres_health(app)

    client = TestClient(app)
    response = client.get("/api/health/module/postgres")

    assert response.status_code == status.HTTP_200_OK
    body = response.json()
    assert body["status"] == "ok"
    assert body["module"] == "db_postgres"
    assert body["pool"] == {"size": 5, "overflow": 0}
    assert body["url"] == "postgresql://masked"
