"""DuckDB session facade for the Keboola Storage API extension.

Parallel of `connectors/bigquery/access.py:BqAccess`. The materialized
Keboola SQL path needs a one-shot DuckDB connection with the Keboola
extension installed, loaded, and ATTACHed; this facade encapsulates
that wiring so `_run_materialized_pass` doesn't need to know the
extension name, the ATTACH alias, or how the token gets quoted into
the URL literal.
"""
from __future__ import annotations
from contextlib import contextmanager
from typing import Iterator

import duckdb


class KeboolaAccess:
    """Lazy DuckDB session manager for the Keboola Storage API extension.

    Single-use — call `.duckdb_session()` as a context manager once per
    materialized job.
    """

    def __init__(self, *, url: str, token: str) -> None:
        if not url or not token:
            raise ValueError("KeboolaAccess requires url and token")
        # Strip trailing slash — the Keboola DuckDB extension's ATTACH
        # fails with a network error when the URL ends in `/` (e.g. the
        # canonical `https://connection.<region>.keboola.com/` form).
        # Bare host works.
        self._url = url.rstrip("/")
        self._token = token

    @contextmanager
    def duckdb_session(self) -> Iterator[duckdb.DuckDBPyConnection]:
        conn = duckdb.connect(":memory:")
        try:
            conn.execute("INSTALL keboola FROM community")
            conn.execute("LOAD keboola")
            escaped_token = self._token.replace("'", "''")
            conn.execute(
                f"ATTACH '{self._url}' AS kbc "
                f"(TYPE keboola, TOKEN '{escaped_token}')"
            )
            yield conn
        finally:
            conn.close()
