"""
Lazy resolution of downstream service URLs and timeouts.

Reading `os.getenv` at module import has two costs we kept paying:
  * a missing variable surfaced as `Invalid URL 'None/gbaiapi/ice_upload'`
    from deep inside `requests`, naming neither the agent nor the variable;
  * a variable added to a running container was ignored until restart.

Resolving at call time fixes both, and lets a missing URL raise a precise
error that the API layer turns into a 503 naming the exact variable to set.
"""
import os


class ServiceNotConfigured(RuntimeError):
    """A downstream service URL is absent from the environment."""

    def __init__(self, env_names, agent: str = None):
        self.env_names = tuple(env_names)
        self.agent = agent

        primary = self.env_names[0]
        alternatives = ""
        if len(self.env_names) > 1:
            alternatives = f" (or {', '.join(self.env_names[1:])})"
        target = f" — required by the '{agent}' agent" if agent else ""

        super().__init__(
            f"{primary}{alternatives} is not configured on this server{target}"
        )


def resolve_service_url(*env_names: str, default: str = None, agent: str = None) -> str:
    """
    First non-empty variable wins, then `default`.
    Raises ServiceNotConfigured when nothing is set and there is no default.
    """
    for name in env_names:
        value = (os.getenv(name) or "").strip()
        if value:
            return value.rstrip("/")

    if default:
        return default.rstrip("/")

    raise ServiceNotConfigured(env_names, agent)


def resolve_timeout(env_name: str, default: int) -> int:
    raw = os.getenv(env_name)
    if not raw:
        return default
    try:
        return int(raw)
    except (TypeError, ValueError):
        return default


def build_url(base: str, endpoint: str) -> str:
    return f"{base.rstrip('/')}/{endpoint.lstrip('/')}"
