package com.easyagents.agent.runtime.agentscope;

import com.easyagents.agent.runtime.model.AgentHttpVersionPolicy;
import io.agentscope.core.model.transport.HttpTransport;
import io.agentscope.core.model.transport.HttpTransportConfig;
import io.agentscope.core.model.transport.HttpTransportFactory;
import io.agentscope.core.model.transport.HttpVersion;
import io.agentscope.core.model.transport.JdkHttpTransport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.URI;
import java.net.http.HttpClient;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 按 HTTP 版本策略提供进程级共享的 AgentScope Transport。
 */
public final class AgentHttpTransportProvider {

    private static final Logger LOG = LoggerFactory.getLogger(AgentHttpTransportProvider.class);
    private static final AgentHttpTransportProvider SHARED = new AgentHttpTransportProvider();

    private final Map<AgentHttpVersionPolicy, HttpTransport> transports = new ConcurrentHashMap<>();

    /**
     * 创建 Transport 提供器。
     */
    private AgentHttpTransportProvider() {
    }

    /**
     * 获取进程级共享提供器。
     *
     * @return 共享提供器
     */
    public static AgentHttpTransportProvider shared() {
        return SHARED;
    }

    /**
     * 获取指定策略与基础 URL 对应的共享 Transport。
     *
     * @param policy HTTP 版本策略
     * @param baseUrl 最终生效的模型基础 URL
     * @return 共享 Transport
     */
    public HttpTransport getTransport(AgentHttpVersionPolicy policy, String baseUrl) {
        AgentHttpVersionPolicy effectivePolicy = resolveEffectivePolicy(policy, baseUrl);
        if (effectivePolicy == AgentHttpVersionPolicy.AUTO) {
            return HttpTransportFactory.getDefault();
        }
        return transports.computeIfAbsent(effectivePolicy, this::createTransport);
    }

    /**
     * 解析请求实际使用的 HTTP 策略。
     *
     * <p>明文 HTTP 固定使用 HTTP/1.1，避免 JDK 客户端发起 h2c Upgrade；HTTPS
     * 保持 HTTP/2 优先并允许底层通过 ALPN 回退。显式策略始终覆盖 URL 判断。</p>
     *
     * @param policy 配置的 HTTP 版本策略
     * @param baseUrl 最终生效的模型基础 URL
     * @return 实际生效策略；无法识别 URL 时返回 AUTO
     */
    public static AgentHttpVersionPolicy resolveEffectivePolicy(AgentHttpVersionPolicy policy, String baseUrl) {
        AgentHttpVersionPolicy safePolicy = policy == null ? AgentHttpVersionPolicy.AUTO : policy;
        if (safePolicy != AgentHttpVersionPolicy.AUTO) {
            return safePolicy;
        }
        if (baseUrl == null || baseUrl.isBlank()) {
            LOG.warn("Agent HTTP AUTO policy cannot infer protocol because base URL is missing; fallback to default transport");
            return AgentHttpVersionPolicy.AUTO;
        }
        try {
            String scheme = URI.create(baseUrl.trim()).getScheme();
            if (scheme == null) {
                return AgentHttpVersionPolicy.AUTO;
            }
            String normalizedScheme = scheme.toLowerCase(Locale.ROOT);
            if ("http".equals(normalizedScheme)) {
                return AgentHttpVersionPolicy.HTTP_1_1;
            }
            if ("https".equals(normalizedScheme)) {
                return AgentHttpVersionPolicy.HTTP_2_PREFERRED;
            }
            LOG.warn("Agent HTTP AUTO policy does not support URL scheme '{}'; fallback to default transport",
                    normalizedScheme);
            return AgentHttpVersionPolicy.AUTO;
        } catch (IllegalArgumentException exception) {
            LOG.warn("Agent HTTP AUTO policy cannot parse base URL; fallback to default transport");
            return AgentHttpVersionPolicy.AUTO;
        }
    }

    /**
     * 创建并注册受 AgentScope 生命周期管理的 JDK Transport。
     *
     * @param policy HTTP 版本策略
     * @return 新 Transport
     */
    private HttpTransport createTransport(AgentHttpVersionPolicy policy) {
        HttpVersion httpVersion = resolveHttpVersion(policy);
        HttpTransportConfig config = HttpTransportConfig.builder()
                .httpVersion(httpVersion)
                .build();
        HttpClient httpClient = HttpClient.newBuilder()
                .version(httpVersion.toJdkHttpVersion())
                .followRedirects(HttpClient.Redirect.NORMAL)
                .connectTimeout(config.getConnectTimeout())
                .build();
        HttpTransport transport = new JdkHttpTransport(httpClient, config);
        // 注册后由 AgentScope JVM shutdown hook 统一关闭，避免每次 Agent 运行创建连接池。
        HttpTransportFactory.register(transport);
        return transport;
    }

    /**
     * 将中立策略映射为 AgentScope HTTP 版本。
     *
     * @param policy HTTP 版本策略
     * @return AgentScope HTTP 版本
     */
    static HttpVersion resolveHttpVersion(AgentHttpVersionPolicy policy) {
        if (policy == AgentHttpVersionPolicy.HTTP_1_1) {
            return HttpVersion.HTTP_1_1;
        }
        return HttpVersion.HTTP_2;
    }
}
