package com.easyagents.agent.runtime.agentscope;

import com.easyagents.agent.runtime.AgentRuntimeException;
import com.easyagents.agent.runtime.model.AgentGenerationOptions;
import com.easyagents.agent.runtime.model.AgentHttpVersionPolicy;
import com.easyagents.agent.runtime.model.AgentModelProviderType;
import com.easyagents.agent.runtime.model.AgentModelSpec;
import io.agentscope.core.model.transport.HttpTransport;
import io.agentscope.core.model.transport.HttpTransportFactory;
import io.agentscope.core.model.transport.HttpVersion;
import io.agentscope.core.model.transport.JdkHttpTransport;
import org.junit.Assert;
import org.junit.Test;

import java.lang.reflect.Field;
import java.net.http.HttpClient;

/**
 * Agent HTTP Transport 策略测试。
 */
public class AgentHttpTransportProviderTest {

    /**
     * 验证相同策略复用 Transport，且显式策略使用预期 JDK HTTP 版本。
     *
     * @throws Exception 反射读取 JDK client 失败时抛出
     */
    @Test
    public void shouldReuseTransportAndConfigureExpectedHttpVersion() throws Exception {
        AgentHttpTransportProvider provider = AgentHttpTransportProvider.shared();

        HttpTransport http11 = provider.getTransport(AgentHttpVersionPolicy.HTTP_1_1, "https://example.com");
        HttpTransport http11Again = provider.getTransport(AgentHttpVersionPolicy.HTTP_1_1, "http://example.com");
        HttpTransport http2 = provider.getTransport(AgentHttpVersionPolicy.HTTP_2_PREFERRED, "http://example.com");

        Assert.assertSame(http11, http11Again);
        Assert.assertNotSame(http11, http2);
        Assert.assertEquals(HttpClient.Version.HTTP_1_1, httpClient(http11).version());
        Assert.assertEquals(HttpClient.Version.HTTP_2, httpClient(http2).version());
        Assert.assertTrue(HttpTransportFactory.isManaged(http11));
        Assert.assertTrue(HttpTransportFactory.isManaged(http2));
        Assert.assertEquals(HttpVersion.HTTP_1_1,
                AgentHttpTransportProvider.resolveHttpVersion(AgentHttpVersionPolicy.HTTP_1_1));
        Assert.assertEquals(HttpVersion.HTTP_2,
                AgentHttpTransportProvider.resolveHttpVersion(AgentHttpVersionPolicy.HTTP_2_PREFERRED));
    }

    /**
     * 验证 AUTO 根据 URL 协议选择安全 Transport。
     *
     * @throws Exception 反射读取 JDK client 失败时抛出
     */
    @Test
    public void autoShouldResolveTransportFromBaseUrlScheme() throws Exception {
        AgentHttpTransportProvider provider = AgentHttpTransportProvider.shared();
        HttpTransport http = provider.getTransport(AgentHttpVersionPolicy.AUTO, "http://example.com/v1");
        HttpTransport https = provider.getTransport(AgentHttpVersionPolicy.AUTO, "https://example.com/v1");
        HttpTransport unknown = provider.getTransport(AgentHttpVersionPolicy.AUTO, "example.com/v1");

        Assert.assertSame(provider.getTransport(AgentHttpVersionPolicy.HTTP_1_1, null), http);
        Assert.assertSame(provider.getTransport(AgentHttpVersionPolicy.HTTP_2_PREFERRED, null), https);
        Assert.assertEquals(HttpClient.Version.HTTP_1_1, httpClient(http).version());
        Assert.assertEquals(HttpClient.Version.HTTP_2, httpClient(https).version());
        Assert.assertSame(HttpTransportFactory.getDefault(), unknown);
        Assert.assertEquals(AgentHttpVersionPolicy.HTTP_1_1,
                AgentHttpTransportProvider.resolveEffectivePolicy(AgentHttpVersionPolicy.AUTO, "HTTP://EXAMPLE.COM"));
        Assert.assertEquals(AgentHttpVersionPolicy.HTTP_2_PREFERRED,
                AgentHttpTransportProvider.resolveEffectivePolicy(AgentHttpVersionPolicy.AUTO, "HTTPS://EXAMPLE.COM"));
        Assert.assertEquals(AgentHttpVersionPolicy.AUTO,
                AgentHttpTransportProvider.resolveEffectivePolicy(AgentHttpVersionPolicy.AUTO, "not a uri"));
    }

    /**
     * 验证不支持注入 Transport 的 Provider 会返回明确错误。
     */
    @Test
    public void unsupportedProviderShouldRejectExplicitHttpPolicy() {
        AgentModelSpec spec = new AgentModelSpec();
        spec.setProviderType(AgentModelProviderType.ANTHROPIC);
        spec.setModelName("claude-test");
        spec.setApiKey("test-key");
        spec.setHttpVersionPolicy(AgentHttpVersionPolicy.HTTP_1_1);

        try {
            new AgentScopeModelFactory().create(spec, new AgentGenerationOptions());
            Assert.fail("Expected unsupported HTTP transport policy error");
        } catch (AgentRuntimeException exception) {
            Assert.assertTrue(exception.getMessage().contains("HTTP_1_1"));
            Assert.assertTrue(exception.getMessage().contains("ANTHROPIC"));
        }
    }

    /**
     * 获取 Transport 内部复用的 JDK HttpClient。
     *
     * @param transport Transport 实例
     * @return JDK HttpClient
     * @throws Exception 反射失败时抛出
     */
    private HttpClient httpClient(HttpTransport transport) throws Exception {
        Assert.assertTrue(transport instanceof JdkHttpTransport);
        Field field = JdkHttpTransport.class.getDeclaredField("client");
        field.setAccessible(true);
        return (HttpClient) field.get(transport);
    }
}
