"""Andlake platform configuration from environment variables.

All values are populated by KubeSpawner env injection (extraEnv for static
values, pre_spawn_hook for per-user values like tenant ID and access token).
"""

from __future__ import annotations

import os
from dataclasses import dataclass


@dataclass(frozen=True)
class AndlakeConfig:
    """Immutable configuration read from environment variables.

    Service URLs default to in-cluster K8s DNS names. All values can be
    overridden via environment variables.
    """

    # Gateway (notebook-service) — Trino queries go through this
    gateway_url: str
    trino_host: str
    trino_port: int

    # Nessie catalog server
    nessie_uri: str

    # MLflow tracking
    mlflow_tracking_uri: str

    # Defaults
    default_catalog: str
    s3_bucket: str

    # Optional — set by JupyterHub pre_spawn_hook when Keycloak is configured
    tenant_id: str
    access_token: str

    @classmethod
    def from_env(cls) -> AndlakeConfig:
        """Build config from environment variables.

        All values have sensible defaults for in-cluster use.
        """
        return cls(
            gateway_url=os.environ.get(
                "ANDLAKE_GATEWAY_URL", "http://notebook-service:8082"
            ),
            trino_host=os.environ.get("ANDLAKE_TRINO_HOST", "notebook-service"),
            trino_port=int(os.environ.get("ANDLAKE_TRINO_PORT", "8082")),
            nessie_uri=os.environ.get(
                "NESSIE_URI", "http://nessie:19120/api/v2"
            ),
            mlflow_tracking_uri=os.environ.get(
                "MLFLOW_TRACKING_URI", "http://mlflow:5000"
            ),
            default_catalog=os.environ.get("ANDLAKE_DEFAULT_CATALOG", "lake"),
            s3_bucket=os.environ.get("ANDLAKE_S3_BUCKET", "andlake-app"),
            tenant_id=os.environ.get("ANDLAKE_TENANT_ID", ""),
            access_token=os.environ.get("ANDLAKE_ACCESS_TOKEN", ""),
        )


# Module-level singleton (lazy)
_config: AndlakeConfig | None = None


def get_config() -> AndlakeConfig:
    """Return the singleton ``AndlakeConfig`` instance.

    The config is built once from environment variables on first call,
    then cached for the lifetime of the process.
    """
    global _config
    if _config is None:
        _config = AndlakeConfig.from_env()
    return _config


def reset_config() -> None:
    """Reset the cached config (useful for testing)."""
    global _config
    _config = None
