from __future__ import annotations

import os
from typing import Any


def _env_bool(name: str, default: bool = False) -> bool:
    v = os.getenv(name)
    if v is None:
        return default
    return v.strip().lower() in {"1", "true", "yes", "y", "on"}


def _env_int(name: str) -> int | None:
    v = os.getenv(name)
    if v is None or not v.strip():
        return None
    return int(v)


def make_session(
    *,
    pooling_on: bool | None = None,
    min_pool_size: int | None = None,
    max_pool_size: int | None = None,
) -> Any:
    """Default session factory using environment variables.

    This is optional sugar so callers can do:

        --session-factory universe_reads.session_factory:make_session

    Connection pooling notes:
    - Pooling is controlled by UOPY config/uopy.ini and by connect() args.
    - Pooling is per-Python-process. Since our reader uses multiprocessing,
      each worker process will have its own pool.
    """

    import uopy  # type: ignore

    host = os.getenv("UV_HOST")
    account = os.getenv("UV_ACCOUNT")
    user = os.getenv("UV_USER")
    password = os.getenv("UV_PASSWORD")

    if not user or not password:
        raise RuntimeError("UV_USER and UV_PASSWORD are required")

    kwargs: dict[str, Any] = {
        "user": user,
        "password": password,
    }

    # Optional connection parameters
    if host:
        kwargs["host"] = host
    if account:
        kwargs["account"] = account

    port = _env_int("UV_PORT")
    if port is not None:
        kwargs["port"] = port

    timeout = _env_int("UV_TIMEOUT")
    if timeout is not None:
        kwargs["timeout"] = timeout

    service = os.getenv("UV_SERVICE")
    if service:
        kwargs["service"] = service

    encoding = os.getenv("UV_ENCODING")
    if encoding:
        kwargs["encoding"] = encoding

    ssl = os.getenv("UV_SSL")
    if ssl is not None:
        kwargs["ssl"] = _env_bool("UV_SSL", default=False)

    # Optional pooling overrides.
    # NOTE: In uopy, pooling is controlled by configuration (often uopy.ini).
    # Passing min/max sizes does not necessarily *enable* pooling if it's disabled
    # in the runtime config.
    if pooling_on is None:
        pooling_on = _env_bool("UV_POOLING_ON", default=False)

    if pooling_on:
        if min_pool_size is None:
            min_pool_size = _env_int("UV_MIN_POOL_SIZE") or 1
        if max_pool_size is None:
            max_pool_size = _env_int("UV_MAX_POOL_SIZE") or 10

        kwargs["min_pool_size"] = int(min_pool_size)
        kwargs["max_pool_size"] = int(max_pool_size)

    return uopy.connect(**kwargs)
