package runner

import (
	"io"
	"net/http"
	"net/http/httptest"
	"testing"

	"github.com/easyai/easyai-ai-gateway/apps/api/internal/config"
	"github.com/easyai/easyai-ai-gateway/apps/api/internal/store"
)

func TestPlatformProxyModeNoneIgnoresEnvironmentProxy(t *testing.T) {
	var proxyHits int
	proxy := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		proxyHits++
		w.WriteHeader(http.StatusTeapot)
	}))
	defer proxy.Close()
	t.Setenv("HTTP_PROXY", proxy.URL)
	t.Setenv("http_proxy", proxy.URL)

	var targetHits int
	target := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		targetHits++
		_, _ = w.Write([]byte("ok"))
	}))
	defer target.Close()

	client, err := testProxyService(config.Config{}).httpClientForCandidate(store.RuntimeModelCandidate{
		PlatformConfig: map[string]any{"networkProxy": map[string]any{"mode": "none"}},
	}, false)
	if err != nil {
		t.Fatalf("build http client: %v", err)
	}
	resp, err := client.Get(target.URL)
	if err != nil {
		t.Fatalf("get target: %v", err)
	}
	_, _ = io.Copy(io.Discard, resp.Body)
	_ = resp.Body.Close()
	if resp.StatusCode != http.StatusOK || targetHits != 1 || proxyHits != 0 {
		t.Fatalf("unexpected status=%d targetHits=%d proxyHits=%d", resp.StatusCode, targetHits, proxyHits)
	}
}

func TestPlatformProxyModeCustomUsesConfiguredHTTPProxy(t *testing.T) {
	var targetHits int
	target := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		targetHits++
		_, _ = w.Write([]byte("target"))
	}))
	defer target.Close()

	var proxyHits int
	proxy := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		proxyHits++
		if r.URL.String() != target.URL && r.URL.String() != target.URL+"/" {
			t.Fatalf("proxy received unexpected target URL %q", r.URL.String())
		}
		_, _ = w.Write([]byte("proxied"))
	}))
	defer proxy.Close()

	client, err := testProxyService(config.Config{}).httpClientForCandidate(store.RuntimeModelCandidate{
		PlatformConfig: map[string]any{"networkProxy": map[string]any{"mode": "custom", "httpProxy": proxy.URL}},
	}, false)
	if err != nil {
		t.Fatalf("build http client: %v", err)
	}
	resp, err := client.Get(target.URL)
	if err != nil {
		t.Fatalf("get target through proxy: %v", err)
	}
	_, _ = io.Copy(io.Discard, resp.Body)
	_ = resp.Body.Close()
	if resp.StatusCode != http.StatusOK || proxyHits != 1 || targetHits != 0 {
		t.Fatalf("unexpected status=%d proxyHits=%d targetHits=%d", resp.StatusCode, proxyHits, targetHits)
	}
}

func TestPlatformProxyModeGlobalUsesConfiguredGlobalHTTPProxy(t *testing.T) {
	var targetHits int
	target := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		targetHits++
		_, _ = w.Write([]byte("target"))
	}))
	defer target.Close()

	var proxyHits int
	proxy := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		proxyHits++
		_, _ = w.Write([]byte("proxied"))
	}))
	defer proxy.Close()

	client, err := testProxyService(config.Config{GlobalHTTPProxy: proxy.URL}).httpClientForCandidate(store.RuntimeModelCandidate{
		PlatformConfig: map[string]any{"networkProxy": map[string]any{"mode": "global"}},
	}, false)
	if err != nil {
		t.Fatalf("build http client: %v", err)
	}
	resp, err := client.Get(target.URL)
	if err != nil {
		t.Fatalf("get target through global proxy: %v", err)
	}
	_, _ = io.Copy(io.Discard, resp.Body)
	_ = resp.Body.Close()
	if resp.StatusCode != http.StatusOK || proxyHits != 1 || targetHits != 0 {
		t.Fatalf("unexpected status=%d proxyHits=%d targetHits=%d", resp.StatusCode, proxyHits, targetHits)
	}
}

func testProxyService(cfg config.Config) *Service {
	return &Service{cfg: cfg, httpClients: newHTTPClientCache()}
}
