"""集中式 SSL 配置 —— 应对公司代理/防火墙往证书链注入自签根 CA 的场景。

症状:`[SSL: CERTIFICATE_VERIFY_FAILED] ... self-signed certificate in certificate
chain`。根因通常是企业网络的 TLS 拦截代理(Zscaler/防火墙等)用自签根 CA 重签了
出站 HTTPS。`PYTHONHTTPSVERIFY=0` 对底层 urllib 不可靠(不同 Python 版本行为不一)。

本模块提供 **进程级、一次性** 的修复:覆盖 `ssl._create_default_https_context`——
这是 `urllib.request.urlopen` 在未显式传 `context=` 时构造默认 context 的工厂。覆盖
它即可让进程内 **所有** urllib HTTPS 调用(provider chat、可用性探测、MCP、web 工具)
统一生效,无需在每个 urlopen 站点改代码。

**默认零行为变化**:只有设置了下列环境变量之一才生效。优先级 CA bundle > insecure。

  - AGENTPAAS_CA_BUNDLE / SSL_CERT_FILE / REQUESTS_CA_BUNDLE
      指向公司根 CA 的 PEM 文件。**推荐**:验证仍开启,只是额外信任该 CA → 安全。
  - AGENTPAAS_INSECURE_SSL=1 (或 true/yes/on)
      彻底关闭证书验证。**不安全**,仅限本地开发或完全信任所处网络时用;会打印
      醒目警告。等价于此前手动 monkey-patch,但集中、可控、有日志。
"""
from __future__ import annotations

import logging
import os
import ssl
import warnings

_TRUTHY = {"1", "true", "yes", "on"}
_configured = False  # 幂等:每进程只配一次
_log = logging.getLogger(__name__)


def _ca_bundle_path() -> str:
    """返回首个存在的 CA bundle 文件路径(按优先级),否则空串。"""
    for key in ("AGENTPAAS_CA_BUNDLE", "SSL_CERT_FILE", "REQUESTS_CA_BUNDLE"):
        val = os.environ.get(key)
        if val and os.path.isfile(val):
            return val
    return ""


def ssl_status() -> str:
    """返回当前 SSL 模式的可读描述(供 /health、日志、错误提示复用)。"""
    ca = _ca_bundle_path()
    if ca:
        return f"custom-ca:{ca}"
    if os.environ.get("AGENTPAAS_INSECURE_SSL", "").lower() in _TRUTHY:
        return "insecure"
    return "default"


def configure_ssl(force: bool = False) -> str:
    """按环境变量配置进程级默认 HTTPS context。幂等。返回所选模式。

    在 server 启动、以及 lambdagent.providers 导入时各调一次(都幂等)→ server 与
    bench/CLI/直连内核脚本都覆盖到。
    """
    global _configured
    if _configured and not force:
        return ssl_status()
    _configured = True

    ca = _ca_bundle_path()
    insecure = os.environ.get("AGENTPAAS_INSECURE_SSL", "").lower() in _TRUTHY

    if ca:
        def _factory(*args, **kwargs):
            ctx = ssl.create_default_context(*args, **kwargs)
            try:
                ctx.load_verify_locations(ca)
            except Exception as e:  # 文件坏/格式错 → 不致命,退回默认信任库
                _log.warning("加载 CA bundle 失败 %s: %s(退回系统默认信任库)", ca, e)
            return ctx
        ssl._create_default_https_context = _factory  # type: ignore[attr-defined]
        _log.info("SSL: 已额外信任自定义 CA bundle %s(证书验证仍开启)", ca)
    elif insecure:
        ssl._create_default_https_context = ssl._create_unverified_context  # type: ignore[attr-defined]
        warnings.warn(
            "AGENTPAAS_INSECURE_SSL 已全局关闭 HTTPS 证书验证(不安全,仅限本地开发)",
            stacklevel=2,
        )
        _log.warning("SSL: 证书验证已全局关闭(AGENTPAAS_INSECURE_SSL=1)")
    # 否则保持 Python 默认 → no-op,零行为变化

    return ssl_status()
