// variable_test.go - 变量系统单元测试
//
// 测试覆盖：
//   - 所有内置变量求值
//   - 字符串展开（$var 和 ${var} 格式）
//   - 性能基准测试
//
// 作者：xfy
package variable

import (
	"strings"
	"testing"

	"github.com/valyala/fasthttp"
)

// mockRequestCtx 创建测试用的 fasthttp.RequestCtx
func mockRequestCtx(_ *testing.T) *fasthttp.RequestCtx {
	ctx := &fasthttp.RequestCtx{}

	// 设置请求信息
	ctx.Request.Header.SetMethod("GET")
	ctx.Request.Header.SetRequestURI("/test/path?foo=bar&baz=qux")
	ctx.Request.Header.SetHost("example.com")
	ctx.Request.Header.Set("X-Custom-Header", "custom-value")
	ctx.Request.Header.Set("User-Agent", "Test-Agent/1.0")
	ctx.Request.Header.SetCookie("session", "abc123")

	return ctx
}

// TestBuiltinVariables 测试所有内置变量
func TestBuiltinVariables(t *testing.T) {
	tests := []struct {
		name     string
		varName  string
		expected string
		contains bool // 如果为 true，则检查是否包含
	}{
		{"host", VarHost, "example.com", false},
		{"uri", VarURI, "/test/path", false},
		{"request_uri", VarRequestURI, "/test/path?foo=bar&baz=qux", false},
		{"args", VarArgs, "foo=bar&baz=qux", false},
		{"request_method", VarRequestMethod, "GET", false},
		{"scheme", VarScheme, "http", false},
		{"time_iso8601", VarTimeISO8601, "", true}, // 包含格式特征
		{"time_local", VarTimeLocal, "/", true},    // 包含 /
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			ctx := mockRequestCtx(t)
			vc := NewContext(ctx)
			defer ReleaseContext(vc)

			value, ok := vc.Get(tt.varName)
			if !ok && !tt.contains {
				t.Errorf("expected to find variable %s", tt.varName)
				return
			}

			if tt.contains {
				if !strings.Contains(value, tt.expected) {
					t.Errorf("%s = %q, expected to contain %q", tt.varName, value, tt.expected)
				}
			} else {
				if value != tt.expected {
					t.Errorf("%s = %q, want %q", tt.varName, value, tt.expected)
				}
			}
		})
	}
}

// TestExpandSimple 测试简单变量展开
func TestExpandSimple(t *testing.T) {
	ctx := mockRequestCtx(t)
	vc := NewContext(ctx)
	defer ReleaseContext(vc)

	tests := []struct {
		template string
		expected string
	}{
		{"$host", "example.com"},
		{"$uri", "/test/path"},
		{"$request_method", "GET"},
		{"$scheme", "http"},
		{"Host: $host", "Host: example.com"},
		{"$scheme://$host$uri", "http://example.com/test/path"},
	}

	for _, tt := range tests {
		t.Run(tt.template, func(t *testing.T) {
			result := vc.Expand(tt.template)
			if result != tt.expected {
				t.Errorf("Expand(%q) = %q, want %q", tt.template, result, tt.expected)
			}
		})
	}
}

// TestExpandBrace 测试花括号变量展开
func TestExpandBrace(t *testing.T) {
	ctx := mockRequestCtx(t)
	vc := NewContext(ctx)
	defer ReleaseContext(vc)

	tests := []struct {
		template string
		expected string
	}{
		{"${host}", "example.com"},
		{"${uri}", "/test/path"},
		{"Host: ${host}", "Host: example.com"},
		{"${scheme}://${host}${uri}", "http://example.com/test/path"},
		{"${host}:8080", "example.com:8080"}, // 变量后有字符
		{"pre_${uri}_post", "pre_/test/path_post"},
	}

	for _, tt := range tests {
		t.Run(tt.template, func(t *testing.T) {
			result := vc.Expand(tt.template)
			if result != tt.expected {
				t.Errorf("Expand(%q) = %q, want %q", tt.template, result, tt.expected)
			}
		})
	}
}

// TestExpandMixed 测试混合格式展开
func TestExpandMixed(t *testing.T) {
	ctx := mockRequestCtx(t)
	vc := NewContext(ctx)
	defer ReleaseContext(vc)

	tests := []struct {
		template string
		expected string
	}{
		{"$scheme://${host}$uri", "http://example.com/test/path"},
		{"${scheme}://$host${uri}", "http://example.com/test/path"},
		{"$request_method ${request_uri} HTTP/1.1", "GET /test/path?foo=bar&baz=qux HTTP/1.1"},
	}

	for _, tt := range tests {
		t.Run(tt.template, func(t *testing.T) {
			result := vc.Expand(tt.template)
			if result != tt.expected {
				t.Errorf("Expand(%q) = %q, want %q", tt.template, result, tt.expected)
			}
		})
	}
}

// TestExpandUndefined 测试未定义变量
func TestExpandUndefined(t *testing.T) {
	ctx := mockRequestCtx(t)
	vc := NewContext(ctx)
	defer ReleaseContext(vc)

	tests := []struct {
		template string
		expected string
	}{
		{"$undefined", "$undefined"},     // 保持原样
		{"${undefined}", "${undefined}"}, // 保持原样
		{"$host-$undefined", "example.com-$undefined"},
		{"$host$undefined", "example.com$undefined"},
	}

	for _, tt := range tests {
		t.Run(tt.template, func(t *testing.T) {
			result := vc.Expand(tt.template)
			if result != tt.expected {
				t.Errorf("Expand(%q) = %q, want %q", tt.template, result, tt.expected)
			}
		})
	}
}

// TestExpandEdgeCases 测试边界情况
func TestExpandEdgeCases(t *testing.T) {
	ctx := mockRequestCtx(t)
	vc := NewContext(ctx)
	defer ReleaseContext(vc)

	tests := []struct {
		template string
		expected string
	}{
		{"", ""},                           // 空字符串
		{"no variable", "no variable"},     // 无变量
		{"$", "$"},                         // 只有 $
		{"${", "${"},                       // 未闭合的 ${
		{"$123", "$123"},                   // 数字开头（不是有效变量名）
		{"test$$host", "test$example.com"}, // 双 $
		{"$host$$uri", "example.com$/test/path"},
	}

	for _, tt := range tests {
		t.Run(tt.template, func(t *testing.T) {
			result := vc.Expand(tt.template)
			if result != tt.expected {
				t.Errorf("Expand(%q) = %q, want %q", tt.template, result, tt.expected)
			}
		})
	}
}

// TestCustomVariable 测试自定义变量
func TestCustomVariable(t *testing.T) {
	ctx := mockRequestCtx(t)
	vc := NewContext(ctx)
	defer ReleaseContext(vc)

	// 设置自定义变量
	vc.Set("custom_var", "custom_value")
	vc.Set("app_name", "lolly")

	// 获取自定义变量
	if v, ok := vc.Get("custom_var"); !ok || v != "custom_value" {
		t.Errorf("custom_var = %q, want %q", v, "custom_value")
	}

	// 展开包含自定义变量
	result := vc.Expand("App: $app_name")
	if result != "App: lolly" {
		t.Errorf("Expand = %q, want %q", result, "App: lolly")
	}
}

// TestCustomOverridesBuiltin 测试自定义变量覆盖内置变量
func TestCustomOverridesBuiltin(t *testing.T) {
	ctx := mockRequestCtx(t)
	vc := NewContext(ctx)
	defer ReleaseContext(vc)

	// 设置同名自定义变量
	vc.Set("host", "custom.host.com")

	// 自定义变量应该覆盖内置变量
	result := vc.Expand("$host")
	if result != "custom.host.com" {
		t.Errorf("Expand = %q, want %q", result, "custom.host.com")
	}
}

// TestResponseInfoVariables 测试响应相关变量
func TestResponseInfoVariables(t *testing.T) {
	ctx := mockRequestCtx(t)
	vc := NewContext(ctx)
	defer ReleaseContext(vc)

	// 设置响应信息
	vc.SetResponseInfo(200, 1024, 15000000) // 15ms

	// 需要设置到 ctx 中才能被 builtin getter 获取
	SetResponseInfoInContext(ctx, 200, 1024, 15000000)

	tests := []struct {
		varName  string
		expected string
	}{
		{VarStatus, "200"},
		{VarBodyBytesSent, "1024"},
		{VarRequestTime, "0.015"},
	}

	for _, tt := range tests {
		t.Run(tt.varName, func(t *testing.T) {
			value, ok := vc.Get(tt.varName)
			if !ok {
				t.Errorf("expected to find variable %s", tt.varName)
				return
			}
			if value != tt.expected {
				t.Errorf("%s = %q, want %q", tt.varName, value, tt.expected)
			}
		})
	}
}

// BenchmarkExpandSimple 基准测试：简单变量展开
func BenchmarkExpandSimple(b *testing.B) {
	ctx := &fasthttp.RequestCtx{}
	ctx.Request.Header.SetHost("example.com")
	ctx.Request.Header.SetMethod("GET")
	ctx.Request.Header.SetRequestURI("/test")

	vc := NewContext(ctx)
	defer ReleaseContext(vc)

	template := "$host $request_method $uri"

	b.ResetTimer()
	b.ReportAllocs()

	for b.Loop() {
		_ = vc.Expand(template)
	}
}

// BenchmarkExpandComplex 基准测试：复杂模板展开
func BenchmarkExpandComplex(b *testing.B) {
	ctx := &fasthttp.RequestCtx{}
	ctx.Request.Header.SetHost("example.com")
	ctx.Request.Header.SetMethod("GET")
	ctx.Request.Header.SetRequestURI("/api/v1/users?page=1&limit=10")

	vc := NewContext(ctx)
	defer ReleaseContext(vc)

	// 模拟日志格式
	template := "$remote_addr - - [$time_local] \"$request_method $request_uri HTTP/1.1\" $status $body_bytes_sent"

	b.ResetTimer()
	b.ReportAllocs()

	for b.Loop() {
		_ = vc.Expand(template)
	}
}

// BenchmarkExpandNoVariable 基准测试：无变量字符串
func BenchmarkExpandNoVariable(b *testing.B) {
	ctx := &fasthttp.RequestCtx{}
	vc := NewContext(ctx)
	defer ReleaseContext(vc)

	template := "This is a static string without any variables"

	b.ResetTimer()
	b.ReportAllocs()

	for b.Loop() {
		_ = vc.Expand(template)
	}
}

// BenchmarkExpandBrace 基准测试：花括号变量
func BenchmarkExpandBrace(b *testing.B) {
	ctx := &fasthttp.RequestCtx{}
	ctx.Request.Header.SetHost("example.com")
	ctx.Request.Header.SetMethod("GET")

	vc := NewContext(ctx)
	defer ReleaseContext(vc)

	template := "${scheme}://${host}${uri}"

	b.ResetTimer()
	b.ReportAllocs()

	for b.Loop() {
		_ = vc.Expand(template)
	}
}

// BenchmarkPoolGetPut 基准测试：池的 Get/Put 性能
func BenchmarkPoolGetPut(b *testing.B) {
	ctx := &fasthttp.RequestCtx{}

	b.ResetTimer()
	b.ReportAllocs()

	for b.Loop() {
		vc := NewContext(ctx)
		ReleaseContext(vc)
	}
}

// TestPoolReuse 测试池复用
func TestPoolReuse(t *testing.T) {
	ctx := mockRequestCtx(t)

	// 获取和释放多个 context，确保没有 panic
	for i := range 10 {
		vc := NewContext(ctx)
		vc.Set("key", "value")
		if v, ok := vc.Get("key"); !ok || v != "value" {
			t.Errorf("iteration %d: expected key=value, got %s", i, v)
		}
		ReleaseContext(vc)
	}

	// 验证池在复用（第二次获取应该清除之前的值）
	vc2 := NewContext(ctx)
	if v, ok := vc2.Get("key"); ok {
		t.Errorf("expected key to be cleared after release, got %s", v)
	}
	ReleaseContext(vc2)
}

// TestReleaseNilContext 测试释放 nil context
func TestReleaseNilContext(_ *testing.T) {
	// 不应该 panic
	ReleaseContext(nil)
}

// TestGetBuiltin 测试获取内置变量定义
func TestGetBuiltin(t *testing.T) {
	// 存在的变量
	v := GetBuiltin("host")
	if v == nil || v.Name != "host" {
		t.Error("GetBuiltin('host') should return non-nil with name 'host'")
	}

	// 不存在的变量
	v = GetBuiltin("nonexistent")
	if v != nil {
		t.Error("GetBuiltin('nonexistent') should return nil")
	}
}

// TestEmptyTemplate 测试空模板
func TestEmptyTemplate(t *testing.T) {
	ctx := mockRequestCtx(t)
	vc := NewContext(ctx)
	defer ReleaseContext(vc)

	result := vc.Expand("")
	if result != "" {
		t.Errorf("Expand('') = %q, want empty string", result)
	}
}

// TestReleaseContextWithNil 测试释放 nil
func TestReleaseContextWithNil(_ *testing.T) {
	// 不应该 panic
	ReleaseContext(nil)
}

// TestExpandOnlyDollar 测试只有 $ 的情况
func TestExpandOnlyDollar(t *testing.T) {
	ctx := mockRequestCtx(t)
	vc := NewContext(ctx)
	defer ReleaseContext(vc)

	tests := []struct {
		template string
		expected string
	}{
		{"$", "$"},
		{"test$", "test$"},
		{"$$", "$$"}, // 两个独立的 $
	}

	for _, tt := range tests {
		t.Run(tt.template, func(t *testing.T) {
			result := vc.Expand(tt.template)
			if result != tt.expected {
				t.Errorf("Expand(%q) = %q, want %q", tt.template, result, tt.expected)
			}
		})
	}
}

// TestNewContext_NilMaps 验证 NewContext 能防御性地初始化 nil map。
func TestNewContext_NilMaps(t *testing.T) {
	ctx := mockRequestCtx(t)

	// 向池中放入多个 map 为 nil 的 Context，模拟异常状态
	for range 10 {
		pool.Put(&Context{})
	}

	// 连续获取，确保所有返回的 Context 都能安全使用，不会 panic
	for range 10 {
		vc := NewContext(ctx)

		vc.Set("key", "value")
		if v, ok := vc.Get("key"); !ok || v != "value" {
			t.Errorf("expected key=value, got %q", v)
		}

		// 验证缓存也能正常工作
		if v, ok := vc.Get("host"); !ok || v != "example.com" {
			t.Errorf("expected host=example.com, got %q", v)
		}

		ReleaseContext(vc)
	}
}

// TestPoolFunctions 测试 Pool 相关函数
func TestPoolFunctions(t *testing.T) {
	ctx := mockRequestCtx(t)

	// 测试 NewContext 和 ReleaseContext
	vc := NewContext(ctx)
	if vc == nil {
		t.Fatal("NewContext returned nil")
	}

	// 设置一些值
	vc.Set("test", "value")

	// 释放
	ReleaseContext(vc)

	// 再次获取应该被清空
	vc2 := NewContext(ctx)
	if _, ok := vc2.Get("test"); ok {
		t.Error("expected context to be cleared after ReleaseContext")
	}
	ReleaseContext(vc2)
}

// TestPoolPutNil 测试 ReleaseContext nil
func TestPoolPutNil(_ *testing.T) {
	// 不应该 panic
	ReleaseContext(nil)
}

// TestSetResponseInfo 测试 SetResponseInfo
func TestSetResponseInfo(t *testing.T) {
	ctx := mockRequestCtx(t)
	vc := NewContext(ctx)
	defer ReleaseContext(vc)

	// 设置响应信息
	vc.SetResponseInfo(404, 512, 25000000) // 25ms

	if vc.status != 404 {
		t.Errorf("status = %d, want 404", vc.status)
	}
	if vc.bodySize != 512 {
		t.Errorf("bodySize = %d, want 512", vc.bodySize)
	}
	if vc.duration != 25000000 {
		t.Errorf("duration = %d, want 25000000", vc.duration)
	}
}

// TestSetServerName 测试 SetServerName
func TestSetServerName(t *testing.T) {
	ctx := mockRequestCtx(t)
	vc := NewContext(ctx)
	defer ReleaseContext(vc)

	vc.SetServerName("my-server")
	if vc.serverName != "my-server" {
		t.Errorf("serverName = %q, want 'my-server'", vc.serverName)
	}
}

// TestUpstreamVariables 测试上游变量
func TestUpstreamVariables(t *testing.T) {
	ctx := mockRequestCtx(t)
	vc := NewContext(ctx)
	defer ReleaseContext(vc)

	// 未设置时应该返回默认值 "-"
	tests := []struct {
		varName  string
		expected string
	}{
		{VarUpstreamAddr, "-"},
		{VarUpstreamStatus, "-"},
		{VarUpstreamResponseTime, "-"},
		{VarUpstreamConnectTime, "-"},
		{VarUpstreamHeaderTime, "-"},
	}

	for _, tt := range tests {
		t.Run(tt.varName+"_default", func(t *testing.T) {
			value, ok := vc.Get(tt.varName)
			if !ok {
				t.Errorf("expected variable %s to exist", tt.varName)
				return
			}
			if value != tt.expected {
				t.Errorf("%s = %q, want %q", tt.varName, value, tt.expected)
			}
		})
	}

	// 设置上游变量
	vc.SetUpstreamVars("http://backend:8080", 200, 0.123, 0.001, 0.045)

	// 验证设置后的值
	testsAfter := []struct {
		varName  string
		expected string
	}{
		{VarUpstreamAddr, "http://backend:8080"},
		{VarUpstreamStatus, "200"},
		{VarUpstreamResponseTime, "0.123"},
		{VarUpstreamConnectTime, "0.001"},
		{VarUpstreamHeaderTime, "0.045"},
	}

	for _, tt := range testsAfter {
		t.Run(tt.varName+"_set", func(t *testing.T) {
			value, ok := vc.Get(tt.varName)
			if !ok {
				t.Errorf("expected variable %s to exist", tt.varName)
				return
			}
			if value != tt.expected {
				t.Errorf("%s = %q, want %q", tt.varName, value, tt.expected)
			}
		})
	}
}

// TestUpstreamVariablesInExpand 测试在模板中展开上游变量
func TestUpstreamVariablesInExpand(t *testing.T) {
	ctx := mockRequestCtx(t)
	vc := NewContext(ctx)
	defer ReleaseContext(vc)

	// 设置上游变量
	vc.SetUpstreamVars("http://backend:8080", 200, 0.123, 0.001, 0.045)

	// 测试展开
	template := "$upstream_addr $upstream_status $upstream_response_time"
	result := vc.Expand(template)
	expected := "http://backend:8080 200 0.123"
	if result != expected {
		t.Errorf("Expand = %q, want %q", result, expected)
	}
}

// TestUpstreamVariablesErrorCases 测试上游变量错误情况
func TestUpstreamVariablesErrorCases(t *testing.T) {
	ctx := mockRequestCtx(t)
	vc := NewContext(ctx)
	defer ReleaseContext(vc)

	// 测试各种错误场景
	tests := []struct {
		expected map[string]string
		name     string
		addr     string
		status   int
	}{
		{
			name:   "no backend",
			addr:   "FAILED",
			status: 502,
			expected: map[string]string{
				VarUpstreamAddr:   "FAILED",
				VarUpstreamStatus: "502",
			},
		},
		{
			name:   "timeout",
			addr:   "http://backend:8080",
			status: 504,
			expected: map[string]string{
				VarUpstreamAddr:   "http://backend:8080",
				VarUpstreamStatus: "504",
			},
		},
		{
			name:   "cache hit",
			addr:   "CACHE",
			status: 200,
			expected: map[string]string{
				VarUpstreamAddr:   "CACHE",
				VarUpstreamStatus: "200",
			},
		},
		{
			name:   "websocket success",
			addr:   "ws://backend:8080",
			status: 101,
			expected: map[string]string{
				VarUpstreamAddr:   "ws://backend:8080",
				VarUpstreamStatus: "101",
			},
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			vc.SetUpstreamVars(tt.addr, tt.status, 0, 0, 0)

			for varName, expected := range tt.expected {
				value, ok := vc.Get(varName)
				if !ok {
					t.Errorf("expected variable %s to exist", varName)
					continue
				}
				if value != expected {
					t.Errorf("%s = %q, want %q", varName, value, expected)
				}
			}
		})
	}
}

// TestUpstreamVariablesZeroValues 测试上游变量零值处理
func TestUpstreamVariablesZeroValues(t *testing.T) {
	ctx := mockRequestCtx(t)
	vc := NewContext(ctx)
	defer ReleaseContext(vc)

	// 测试零值应该返回 "-"
	vc.SetUpstreamVars("", 0, 0, 0, 0)

	tests := []struct {
		varName  string
		expected string
	}{
		{VarUpstreamAddr, "-"},
		{VarUpstreamStatus, "-"},
		{VarUpstreamResponseTime, "-"},
		{VarUpstreamConnectTime, "-"},
		{VarUpstreamHeaderTime, "-"},
	}

	for _, tt := range tests {
		t.Run(tt.varName, func(t *testing.T) {
			value, ok := vc.Get(tt.varName)
			if !ok {
				t.Errorf("expected variable %s to exist", tt.varName)
				return
			}
			if value != tt.expected {
				t.Errorf("%s = %q, want %q", tt.varName, value, tt.expected)
			}
		})
	}
}

// BenchmarkUpstreamVariables 基准测试：上游变量
func BenchmarkUpstreamVariables(b *testing.B) {
	ctx := &fasthttp.RequestCtx{}
	ctx.Request.Header.SetHost("example.com")
	ctx.Request.Header.SetMethod("GET")
	ctx.Request.Header.SetRequestURI("/test")

	vc := NewContext(ctx)
	defer ReleaseContext(vc)

	// 设置上游变量
	vc.SetUpstreamVars("http://backend:8080", 200, 0.123, 0.001, 0.045)

	b.ResetTimer()
	b.ReportAllocs()

	for b.Loop() {
		_, _ = vc.Get(VarUpstreamAddr)
		_, _ = vc.Get(VarUpstreamStatus)
		_, _ = vc.Get(VarUpstreamResponseTime)
	}
}

// TestEphemeralGet 测试 EphemeralGet 方法
func TestEphemeralGet(t *testing.T) {
	ctx := mockRequestCtx(t)
	vc := NewContext(ctx)
	defer ReleaseContext(vc)

	tests := []struct {
		name     string
		varName  string
		expected []byte
	}{
		{"host", VarHost, []byte("example.com")},
		{"uri", VarURI, []byte("/test/path")},
		{"request_uri", VarRequestURI, []byte("/test/path?foo=bar&baz=qux")},
		{"args", VarArgs, []byte("foo=bar&baz=qux")},
		{"request_method", VarRequestMethod, []byte("GET")},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			result := vc.EphemeralGet(tt.varName)
			if string(result) != string(tt.expected) {
				t.Errorf("EphemeralGet(%q) = %q, want %q", tt.varName, result, tt.expected)
			}
		})
	}
}

// TestEphemeralGetCustomVariable 测试自定义变量的 EphemeralGet
func TestEphemeralGetCustomVariable(t *testing.T) {
	ctx := mockRequestCtx(t)
	vc := NewContext(ctx)
	defer ReleaseContext(vc)

	// 设置自定义变量
	vc.Set("custom_var", "custom_value")

	result := vc.EphemeralGet("custom_var")
	if string(result) != "custom_value" {
		t.Errorf("EphemeralGet('custom_var') = %q, want 'custom_value'", result)
	}
}

// TestEphemeralGetUndefined 测试未定义变量的 EphemeralGet
func TestEphemeralGetUndefined(t *testing.T) {
	ctx := mockRequestCtx(t)
	vc := NewContext(ctx)
	defer ReleaseContext(vc)

	result := vc.EphemeralGet("undefined_var")
	if result != nil {
		t.Errorf("EphemeralGet('undefined_var') = %q, want nil", result)
	}
}

// TestEphemeralGetCache 测试 EphemeralGet 的缓存
func TestEphemeralGetCache(t *testing.T) {
	ctx := mockRequestCtx(t)
	vc := NewContext(ctx)
	defer ReleaseContext(vc)

	// 第一次获取
	result1 := vc.EphemeralGet(VarHost)
	// 第二次获取应该命中缓存
	result2 := vc.EphemeralGet(VarHost)

	// 验证缓存返回相同的结果
	if string(result1) != string(result2) {
		t.Errorf("EphemeralGet cache: %q != %q", result1, result2)
	}
}

// TestPersistentGet 测试 PersistentGet 方法
func TestPersistentGet(t *testing.T) {
	ctx := mockRequestCtx(t)
	vc := NewContext(ctx)
	defer ReleaseContext(vc)

	tests := []struct {
		name     string
		varName  string
		expected string
	}{
		{"host", VarHost, "example.com"},
		{"uri", VarURI, "/test/path"},
		{"request_method", VarRequestMethod, "GET"},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			result := vc.PersistentGet(tt.varName)
			if result != tt.expected {
				t.Errorf("PersistentGet(%q) = %q, want %q", tt.varName, result, tt.expected)
			}
		})
	}
}

// TestPersistentGetUndefined 测试未定义变量的 PersistentGet
func TestPersistentGetUndefined(t *testing.T) {
	ctx := mockRequestCtx(t)
	vc := NewContext(ctx)
	defer ReleaseContext(vc)

	result := vc.PersistentGet("undefined_var")
	if result != "" {
		t.Errorf("PersistentGet('undefined_var') = %q, want empty string", result)
	}
}

// TestGetBackwardCompatibility 测试 Get 方法的向后兼容性
func TestGetBackwardCompatibility(t *testing.T) {
	ctx := mockRequestCtx(t)
	vc := NewContext(ctx)
	defer ReleaseContext(vc)

	// Get 应该返回与 PersistentGet 相同的结果
	tests := []string{VarHost, VarURI, VarRequestMethod, VarRequestURI}

	for _, varName := range tests {
		getResult, ok := vc.Get(varName)
		if !ok {
			t.Errorf("Get(%q) returned not found", varName)
			continue
		}
		persistentResult := vc.PersistentGet(varName)
		if getResult != persistentResult {
			t.Errorf("Get(%q) = %q, PersistentGet(%q) = %q, should be equal",
				varName, getResult, varName, persistentResult)
		}
	}
}

// TestEphemeralGetUpstreamVariables 测试上游变量的 EphemeralGet
func TestEphemeralGetUpstreamVariables(t *testing.T) {
	ctx := mockRequestCtx(t)
	vc := NewContext(ctx)
	defer ReleaseContext(vc)

	// 未设置时应该返回默认值 "-"
	defaultTests := []struct {
		varName  string
		expected []byte
	}{
		{VarUpstreamAddr, []byte("-")},
		{VarUpstreamStatus, []byte("-")},
		{VarUpstreamResponseTime, []byte("-")},
	}

	for _, tt := range defaultTests {
		t.Run(tt.varName+"_default", func(t *testing.T) {
			result := vc.EphemeralGet(tt.varName)
			if string(result) != string(tt.expected) {
				t.Errorf("EphemeralGet(%q) = %q, want %q", tt.varName, result, tt.expected)
			}
		})
	}

	// 设置上游变量
	vc.SetUpstreamVars("http://backend:8080", 200, 0.123, 0.001, 0.045)

	setTests := []struct {
		varName  string
		expected []byte
	}{
		{VarUpstreamAddr, []byte("http://backend:8080")},
		{VarUpstreamStatus, []byte("200")},
		{VarUpstreamResponseTime, []byte("0.123")},
	}

	for _, tt := range setTests {
		t.Run(tt.varName+"_set", func(t *testing.T) {
			result := vc.EphemeralGet(tt.varName)
			if string(result) != string(tt.expected) {
				t.Errorf("EphemeralGet(%q) = %q, want %q", tt.varName, result, tt.expected)
			}
		})
	}
}

// TestEphemeralGetResponseInfo 测试响应信息的 EphemeralGet
func TestEphemeralGetResponseInfo(t *testing.T) {
	ctx := mockRequestCtx(t)
	vc := NewContext(ctx)
	defer ReleaseContext(vc)

	// 设置响应信息
	vc.SetResponseInfo(200, 1024, 15000000) // 15ms

	tests := []struct {
		varName  string
		expected []byte
	}{
		{VarStatus, []byte("200")},
		{VarBodyBytesSent, []byte("1024")},
		{VarRequestTime, []byte("0.015")},
	}

	for _, tt := range tests {
		t.Run(tt.varName, func(t *testing.T) {
			result := vc.EphemeralGet(tt.varName)
			if string(result) != string(tt.expected) {
				t.Errorf("EphemeralGet(%q) = %q, want %q", tt.varName, result, tt.expected)
			}
		})
	}
}

// BenchmarkEphemeralGet 基准测试：EphemeralGet 零拷贝性能
func BenchmarkEphemeralGet(b *testing.B) {
	ctx := setupBenchmarkRequestCtx()
	vc := NewContext(ctx)
	defer ReleaseContext(vc)

	b.ResetTimer()
	b.ReportAllocs()

	for b.Loop() {
		_ = vc.EphemeralGet(VarHost)
	}
}

// BenchmarkEphemeralGetCached 基准测试：EphemeralGet 缓存命中性能
func BenchmarkEphemeralGetCached(b *testing.B) {
	ctx := setupBenchmarkRequestCtx()
	vc := NewContext(ctx)
	defer ReleaseContext(vc)

	// 预热缓存
	_ = vc.EphemeralGet(VarHost)

	b.ResetTimer()
	b.ReportAllocs()

	for b.Loop() {
		_ = vc.EphemeralGet(VarHost)
	}
}

// BenchmarkPersistentGet 基准测试：PersistentGet 性能
func BenchmarkPersistentGet(b *testing.B) {
	ctx := setupBenchmarkRequestCtx()
	vc := NewContext(ctx)
	defer ReleaseContext(vc)

	b.ResetTimer()
	b.ReportAllocs()

	for b.Loop() {
		_ = vc.PersistentGet(VarHost)
	}
}

// BenchmarkEphemeralGetMultiple 基准测试：获取多个变量的 EphemeralGet
func BenchmarkEphemeralGetMultiple(b *testing.B) {
	ctx := setupBenchmarkRequestCtx()
	vc := NewContext(ctx)
	defer ReleaseContext(vc)

	vars := []string{VarHost, VarURI, VarRequestMethod, VarRequestURI, VarArgs}

	b.ResetTimer()
	b.ReportAllocs()

	for b.Loop() {
		for _, name := range vars {
			_ = vc.EphemeralGet(name)
		}
	}
}
