package service

import (
	"net/http"
	"testing"

	"github.com/stretchr/testify/require"
)

func TestResolveWireCasing(t *testing.T) {
	tests := []struct {
		name string
		key  string
		want string
	}{
		{"accept", "Accept", "Accept"},
		{"user-agent", "User-Agent", "User-Agent"},
		{"x-stainless-retry-count", "X-Stainless-Retry-Count", "X-Stainless-Retry-Count"},
		{"anthropic-version", "anthropic-version", "anthropic-version"},
		{"unknown-header", "Unknown-Header", "Unknown-Header"},
		{"mixed-case", "Mixed-Case", "Mixed-Case"},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			got := resolveWireCasing(tt.key)
			require.Equal(t, tt.want, got)
		})
	}
}

func TestSetHeaderRaw(t *testing.T) {
	h := make(http.Header)
	
	// Test setting header with wire casing
	setHeaderRaw(h, "Accept", "application/json")
	require.Equal(t, "application/json", h.Get("Accept"))
	
	// Test setting header that needs wire casing resolution
	// Note: setHeaderRaw stores with the exact key provided
	setHeaderRaw(h, "accept", "text/html")
	// The header is stored under "accept" (lowercase), not "Accept"
	require.Equal(t, "text/html", h["accept"][0])
	
	// Test overwriting existing header
	setHeaderRaw(h, "User-Agent", "TestAgent")
	setHeaderRaw(h, "user-agent", "NewAgent")
	require.Equal(t, "NewAgent", h["user-agent"][0])
}

func TestAddHeaderRaw(t *testing.T) {
	h := make(http.Header)
	
	// Add first value
	addHeaderRaw(h, "X-Custom", "value1")
	require.Equal(t, []string{"value1"}, h["X-Custom"])
	
	// Add second value
	addHeaderRaw(h, "X-Custom", "value2")
	require.Equal(t, []string{"value1", "value2"}, h["X-Custom"])
}

func TestGetHeaderRaw(t *testing.T) {
	h := make(http.Header)
	h.Set("Accept", "application/json")
	h.Set("anthropic-version", "2023-06-01")
	
	tests := []struct {
		name string
		key  string
		want string
	}{
		{"exact_match", "Accept", "application/json"},
		{"canonical_lookup", "accept", "application/json"},
		{"wire_casing_lookup", "Accept", "application/json"},
		{"lowercase_header", "anthropic-version", "2023-06-01"},
		{"not_exist", "Not-Exist", ""},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			got := getHeaderRaw(h, tt.key)
			require.Equal(t, tt.want, got)
		})
	}
}

func TestSortHeadersByWireOrder(t *testing.T) {
	h := make(http.Header)
	h.Set("Z-Last", "last")
	h.Set("Accept", "application/json")
	h.Set("anthropic-version", "2023-06-01")
	h.Set("User-Agent", "Test")
	
	sorted := sortHeadersByWireOrder(h)
	
	// Check that wire-ordered headers come first
	// Note: h.Set() uses canonical key, so "anthropic-version" becomes "Anthropic-Version"
	require.Contains(t, sorted, "Accept")
	require.Contains(t, sorted, "User-Agent")
	require.Contains(t, sorted, "Anthropic-Version")
	require.Contains(t, sorted, "Z-Last")
	
	// Z-Last should be at the end (not in wire order)
	require.Equal(t, "Z-Last", sorted[len(sorted)-1])
}

func TestHeaderWireOrderSet(t *testing.T) {
	// Verify headerWireOrderSet is initialized correctly
	require.NotNil(t, headerWireOrderSet)
	require.Greater(t, len(headerWireOrderSet), 0)
	
	// Check some expected keys exist
	require.Contains(t, headerWireOrderSet, "accept")
	require.Contains(t, headerWireOrderSet, "user-agent")
	require.Contains(t, headerWireOrderSet, "anthropic-version")
}
