import logging
from typing import Any

try:
    from pymongo import AsyncMongoClient
    from pymongo.asynchronous.database import AsyncDatabase
    from pymongo.errors import PyMongoError
except ImportError:
    raise RuntimeError("Mongodb extra is not installed. Run `pip install snakestack[mongodb]`.")

from snakestack.config import SnakeStackSettings


class DB:
    client: AsyncMongoClient[Any]

db = DB()

logger = logging.getLogger(__name__)


async def open_mongodb_connection(
    settings: SnakeStackSettings
) -> None:
    logger.debug("Connecting to mongodb...")
    if not settings.mongo.uri.startswith("mongodb"):
        raise ValueError("Invalid MongoDB URL configured.")
    db.client = AsyncMongoClient(
        settings.mongo.get_host(),
        **settings.mongo.get_kwargs()
    )
    logger.debug("Connecting to mongodb successful.")


async def close_mongodb_connection() -> None:
    logger.debug("Closing connection with mongodb...")
    if db.client:
        await db.client.close()
    logger.debug("Connection with mongodb is closed.")


def get_database(
    settings: SnakeStackSettings
) -> AsyncDatabase[Any]:
    if not db.client:
        raise RuntimeError("Connection with mongodb is not starting.")
    return db.client[settings.mongo.dbname]


async def ping() -> bool:
    if not db.client:
        raise RuntimeError("Connection with mongodb is not starting.")
    try:
        await db.client.admin.command("ping")
        return True
    except PyMongoError:
        return False
