"""Environment helpers for resolving managed publish targets."""

from __future__ import annotations

import os
from functools import lru_cache
from typing import Any, Dict, Mapping, Optional

from .client import APIClient, APIError
from .config import Config


class PublishConfigError(RuntimeError):
    """Raised when the SDK cannot determine publish defaults from the API."""


@lru_cache(maxsize=8)
def _fetch_publish_config(env: str) -> Dict[str, Any]:
    client = APIClient()
    payload = client.get_publish_config() or {}
    if not isinstance(payload, Mapping):
        raise PublishConfigError("Publish config response must be an object")
    payload = dict(payload)
    payload.setdefault("environment", env)
    return payload


def get_publish_defaults(env: Optional[str] = None, *, force_refresh: bool = False) -> Dict[str, Any]:
    """Return managed publish registry/UI defaults.

    Args:
        env: Optional explicit environment (dev/staging/prod). Defaults to current env.
        force_refresh: When True, bypass the memoized cache.
    """

    target_env = env or Config.get_environment()
    if force_refresh:
        _fetch_publish_config.cache_clear()

    # Set environment before calling the cached function so the global
    # side-effect is not trapped inside the lru_cache closure.
    previous_env = os.environ.get("HLA_COMPASS_ENV")
    Config.set_environment(target_env)

    try:
        return dict(_fetch_publish_config(target_env))
    except APIError as exc:  # pragma: no cover - network/env specific
        raise PublishConfigError(str(exc)) from exc
    finally:
        if previous_env is None:
            os.environ.pop("HLA_COMPASS_ENV", None)
        else:
            Config.set_environment(previous_env)
