"""运行时配置读取工具。

该模块负责从环境变量中解析回调地址与出口 IP 白名单等信息，并提供缓存能力。
"""
from __future__ import annotations

import os
from functools import lru_cache
from typing import List, Optional

CALLBACK_URL_ENV = "AUTH_CALLBACK_URL"
CALLBACK_BASE_ENV = "AUTH_CALLBACK_BASE_URL"
CALLBACK_PATH_ENV = "AUTH_CALLBACK_PATH"
IP_ALLOWLIST_ENV = "AUTH_IP_ALLOWLIST"
LEGACY_IP_ALLOWLIST_ENV = "AUTH_WHITELIST_IPS"
API_KEY_ENV = "AUTH_API_KEY"
_DEFAULT_CALLBACK_PATH = "/oauth/callback"


def _normalize_url(base: str, path: str) -> str:
    base = base.strip()
    path = path.strip()
    if not base:
        return ""
    if path and not path.startswith("/"):
        path = "/" + path
    if not path:
        return base.rstrip("/")
    return base.rstrip("/") + path


@lru_cache(maxsize=None)
def get_callback_url() -> Optional[str]:
    """返回当前服务的回调地址。"""
    direct = os.getenv(CALLBACK_URL_ENV)
    if direct and direct.strip():
        return direct.strip()

    base = os.getenv(CALLBACK_BASE_ENV, "").strip()
    if not base:
        return None
    path = os.getenv(CALLBACK_PATH_ENV, _DEFAULT_CALLBACK_PATH)
    url = _normalize_url(base, path)
    return url or None


@lru_cache(maxsize=None)
def get_ip_allow_list() -> List[str]:
    """返回出口 IP 白名单。"""
    raw = os.getenv(IP_ALLOWLIST_ENV)
    if raw and raw.strip():
        values = raw.replace("\n", ",").split(",")
    else:
        legacy = os.getenv(LEGACY_IP_ALLOWLIST_ENV, "")
        values = legacy.replace("\n", ",").split(",") if legacy else []
    cleaned: List[str] = []
    for item in values:
        normalized = item.strip()
        if normalized:
            cleaned.append(normalized)
    return cleaned


def reset_runtime_cache() -> None:
    """清空缓存，便于单元测试重新读取环境变量。"""
    get_callback_url.cache_clear()
    get_ip_allow_list.cache_clear()
    get_api_key.cache_clear()


@lru_cache(maxsize=None)
def get_api_key() -> Optional[str]:
    """返回配置的 API Key（若未配置则返回 None）。

    读取环境变量 `AUTH_API_KEY`。为空或仅空白则视为未配置，不启用鉴权。
    """
    raw = os.getenv(API_KEY_ENV, "")
    if raw and raw.strip():
        return raw.strip()
    return None

__all__ = ["get_callback_url", "get_ip_allow_list", "get_api_key", "reset_runtime_cache"]
