"""DuckDB connection configuration.

This module defines a small Pydantic model for configuring a DuckDB connection.
You typically use it through the :class:`relationalai.config.create_config` factory function
by adding a DuckDB connection entry under the ``connections`` keyword argument.

The connection entry can be provided as either:

- A Python dict (recommended for config files), or
- An instance of :class:`~relationalai.config.connections.duckdb.DuckDBConnection`
  (useful when building configs programmatically).

Calling :meth:`~relationalai.config.connections.duckdb.DuckDBConnection.get_session`
creates and caches the underlying :class:`duckdb.DuckDBPyConnection`.

Examples
--------
Configure an in-memory DuckDB connection:

>>> from relationalai.config import Config
>>> cfg = Config(connections={"local": {"type": "duckdb", "path": ":memory:"}})

Configure a file-backed DuckDB connection:

>>> from relationalai.config import Config
>>> cfg = Config(connections={"local": {"type": "duckdb", "path": "./my.db"}})
"""

from __future__ import annotations

from typing import Literal, Any, TYPE_CHECKING
from pydantic import Field

if TYPE_CHECKING:
    import duckdb  # type: ignore[import-not-found]

from ...util.docutils import include_in_docs

from .base import BaseConnection


# include this module in documentation
__include_in_docs__ = True


@include_in_docs
class DuckDBConnection(BaseConnection):
    """Configure a DuckDB connection.

    Use this when you want to run PyRel against DuckDB (either a file-backed
    database or ``":memory:"``). The underlying :class:`duckdb.DuckDBPyConnection`
    is created by :meth:`get_session` and cached on the instance.

    Attributes
    ----------
    path : str
        Path to the DuckDB database file, or ``":memory:"`` for an in-memory database.
    read_only : bool, optional
        Whether to open the database in read-only mode.
    config : dict[str, Any], optional
        Extra DuckDB connection options passed through to ``duckdb.connect``.

    Examples
    --------
    >>> from relationalai.config import Config, DuckDBConnection
    >>> cfg = Config(connections={"local": DuckDBConnection(path=":memory:")}, default_connection="local")
    >>> conn = cfg.get_session(DuckDBConnection)
    """

    type: Literal["duckdb"] = "duckdb"

    path: str = Field(..., description="Path to DuckDB database file (or ':memory:' for in-memory)")
    read_only: bool = Field(False, description="Open database in read-only mode")
    config: dict[str, Any] | None = Field(None, description="Additional DuckDB configuration options")

    def get_session(self) -> duckdb.DuckDBPyConnection:
        import duckdb  # type: ignore[import-not-found]

        if self._cached_session is None:
            self._cached_session = duckdb.connect(
                database=self.path,
                read_only=self.read_only,
                config=self.config or {}
            )

        return self._cached_session
