// Package http3 提供 HTTP/3 适配器的基准测试。
//
// 该文件测试 HTTP/3 适配器的性能，包括：
//   - Handler 包装开销
//   - HTTP 请求到 fasthttp 请求的转换性能
//   - 不同大小 Body 的读取性能
//   - fasthttp 响应到 HTTP 响应的转换性能
//   - RequestCtx sync.Pool 复用效率
//
// 作者：xfy
package http3

import (
	"bytes"
	"io"
	"net/http"
	"net/url"
	"testing"

	"github.com/valyala/fasthttp"
)

// BenchmarkAdapterWrap 测试 Handler 包装开销
//
// 该基准测试测量将 fasthttp.RequestHandler 包装为 http.Handler 的基本开销，
// 包括 ctxPool 获取和放回操作。
func BenchmarkAdapterWrap(b *testing.B) {
	adapter := NewAdapter()

	// 简单的 fasthttp handler
	handler := func(ctx *fasthttp.RequestCtx) {
		ctx.SetStatusCode(200)
		ctx.SetBodyString("OK")
	}

	httpHandler := adapter.Wrap(handler)

	// 创建请求
	req := &http.Request{
		Method: "GET",
		URL:    &url.URL{Path: "/test"},
		Host:   "localhost",
		Header: http.Header{},
	}

	b.ResetTimer()
	b.ReportAllocs()

	for b.Loop() {
		rw := &mockResponseWriter{}
		httpHandler.ServeHTTP(rw, req)
	}
}

// BenchmarkAdapterConvertRequest 测试 HTTP -> fasthttp 头部转换性能
//
// 该基准测试测量 convertRequest 方法在仅有头部转换时的性能，
// 不包含 Body 读取的开销。
func BenchmarkAdapterConvertRequest(b *testing.B) {
	adapter := NewAdapter()

	// 创建包含多个头部的请求
	req := &http.Request{
		Method: "POST",
		URL:    &url.URL{Path: "/api/v1/users", RawQuery: "page=1&limit=10"},
		Host:   "api.example.com",
		Header: http.Header{
			"Content-Type":    []string{"application/json"},
			"Accept":          []string{"application/json"},
			"Authorization":   []string{"Bearer token123456"},
			"X-Request-ID":    []string{"req-123456789"},
			"X-User-Agent":    []string{"TestClient/1.0"},
			"Accept-Encoding": []string{"gzip, deflate"},
			"Cache-Control":   []string{"no-cache"},
			"Connection":      []string{"keep-alive"},
		},
		RemoteAddr: "192.168.1.100:12345",
	}

	ctx := &fasthttp.RequestCtx{}
	ctx.Init(&fasthttp.Request{}, nil, nil)

	b.ResetTimer()
	b.ReportAllocs()

	for b.Loop() {
		ctx.Request.Reset()
		adapter.convertRequest(req, ctx)
	}
}

// BenchmarkAdapterConvertRequestBody_1KB 测试 1KB Body 读取性能
//
// 该基准测试测量 io.ReadAll 在 1KB Body 大小下的开销。
func BenchmarkAdapterConvertRequestBody_1KB(b *testing.B) {
	benchmarkAdapterConvertRequestBody(b, 1024)
}

// BenchmarkAdapterConvertRequestBody_10KB 测试 10KB Body 读取性能
//
// 该基准测试测量 io.ReadAll 在 10KB Body 大小下的开销。
func BenchmarkAdapterConvertRequestBody_10KB(b *testing.B) {
	benchmarkAdapterConvertRequestBody(b, 10*1024)
}

// BenchmarkAdapterConvertRequestBody_100KB 测试 100KB Body 读取性能
//
// 该基准测试测量 io.ReadAll 在 100KB Body 大小下的开销。
func BenchmarkAdapterConvertRequestBody_100KB(b *testing.B) {
	benchmarkAdapterConvertRequestBody(b, 100*1024)
}

// benchmarkAdapterConvertRequestBody 是 Body 读取性能的通用基准测试函数
//
// 参数：
//   - b: 测试对象
//   - bodySize: Body 大小（字节）
func benchmarkAdapterConvertRequestBody(b *testing.B, bodySize int) {
	adapter := NewAdapter()
	bodyData := make([]byte, bodySize)
	for i := range bodyData {
		bodyData[i] = byte('a' + (i % 26))
	}

	b.ResetTimer()
	b.ReportAllocs()

	for b.Loop() {
		b.StopTimer()
		// 每次迭代创建新的 Body，模拟新的请求
		req := &http.Request{
			Method: "POST",
			URL:    &url.URL{Path: "/upload"},
			Host:   "localhost",
			Header: http.Header{
				"Content-Type": []string{"application/octet-stream"},
			},
			Body:          io.NopCloser(bytes.NewReader(bodyData)),
			ContentLength: int64(bodySize),
		}
		ctx := &fasthttp.RequestCtx{}
		ctx.Init(&fasthttp.Request{}, nil, nil)
		b.StartTimer()

		adapter.convertRequest(req, ctx)
	}
}

// BenchmarkAdapterConvertResponse 测试 fasthttp -> HTTP 响应转换性能
//
// 该基准测试测量 convertResponse 方法的性能，包括：
//   - 状态码提取
//   - 响应头部复制
//   - 响应体写入
func BenchmarkAdapterConvertResponse(b *testing.B) {
	adapter := NewAdapter()

	// 预创建响应内容
	responseBody := []byte(`{"status":"success","data":{"id":12345,"name":"test","items":[1,2,3,4,5]}}`)

	ctx := &fasthttp.RequestCtx{}
	ctx.Init(&fasthttp.Request{}, nil, nil)
	ctx.SetStatusCode(200)
	ctx.Response.Header.Set("Content-Type", "application/json")
	ctx.Response.Header.Set("X-Response-ID", "resp-123456")
	ctx.Response.Header.Set("Cache-Control", "no-store")
	ctx.SetBody(responseBody)

	b.ResetTimer()
	b.ReportAllocs()

	for b.Loop() {
		b.StopTimer()
		rw := &mockResponseWriter{}
		b.StartTimer()

		adapter.convertResponse(ctx, rw)
	}
}

// BenchmarkAdapterCtxPool 测试 RequestCtx sync.Pool 复用效率
//
// 该基准测试比较使用 sync.Pool 复用 RequestCtx 与每次创建新对象的性能差异。
func BenchmarkAdapterCtxPool(b *testing.B) {
	b.Run("WithPool", func(b *testing.B) {
		adapter := NewAdapter()
		handler := func(ctx *fasthttp.RequestCtx) {
			ctx.SetStatusCode(200)
		}
		httpHandler := adapter.Wrap(handler)
		req := &http.Request{
			Method: "GET",
			URL:    &url.URL{Path: "/"},
			Host:   "localhost",
		}

		b.ResetTimer()
		b.ReportAllocs()

		for b.Loop() {
			rw := &mockResponseWriter{}
			httpHandler.ServeHTTP(rw, req)
		}
	})

	b.Run("WithoutPool", func(b *testing.B) {
		handler := func(ctx *fasthttp.RequestCtx) {
			ctx.SetStatusCode(200)
		}
		req := &http.Request{
			Method: "GET",
			URL:    &url.URL{Path: "/"},
			Host:   "localhost",
		}

		b.ResetTimer()
		b.ReportAllocs()

		for b.Loop() {
			rw := &mockResponseWriter{}
			// 每次创建新的 ctx，不使用 Pool
			ctx := &fasthttp.RequestCtx{}
			ctx.Init(&fasthttp.Request{}, nil, nil)
			ctx.Request.Header.SetMethod(req.Method)
			ctx.Request.SetRequestURI(req.URL.Path)
			ctx.Request.Header.SetHost(req.Host)
			handler(ctx)
			// 模拟响应写入
			if ctx.Response.StatusCode() == 0 {
				rw.status = 200
			} else {
				rw.status = ctx.Response.StatusCode()
			}
		}
	})
}

// BenchmarkAdapterConvertRequest_Parallel 测试并发环境下的请求转换性能
//
// 该基准测试使用 b.RunParallel 模拟并发请求场景。
func BenchmarkAdapterConvertRequest_Parallel(b *testing.B) {
	adapter := NewAdapter()

	req := &http.Request{
		Method: "POST",
		URL:    &url.URL{Path: "/api/data", RawQuery: "key=value"},
		Host:   "localhost",
		Header: http.Header{
			"Content-Type": []string{"application/json"},
			"X-Request-ID": []string{"parallel-test"},
		},
	}

	b.ResetTimer()
	b.ReportAllocs()

	b.RunParallel(func(pb *testing.PB) {
		for pb.Next() {
			ctx := &fasthttp.RequestCtx{}
			ctx.Init(&fasthttp.Request{}, nil, nil)
			adapter.convertRequest(req, ctx)
		}
	})
}

// BenchmarkAdapterFullRoundTrip 测试完整的请求-响应往返性能
//
// 该基准测试模拟真实的 HTTP/3 请求处理流程，包括：
//   - 请求转换
//   - fasthttp handler 执行
//   - 响应转换
func BenchmarkAdapterFullRoundTrip(b *testing.B) {
	adapter := NewAdapter()

	// 模拟真实的 API handler
	apiHandler := func(ctx *fasthttp.RequestCtx) {
		// 模拟一些业务逻辑
		method := string(ctx.Method())
		path := string(ctx.Path())

		if method == "GET" && string(path) == "/api/users" {
			ctx.SetStatusCode(200)
			ctx.Response.Header.Set("Content-Type", "application/json")
			ctx.SetBodyString(`{"users":[{"id":1,"name":"Alice"},{"id":2,"name":"Bob"}]}`)
		} else {
			ctx.SetStatusCode(404)
			ctx.SetBodyString(`{"error":"not found"}`)
		}
	}

	httpHandler := adapter.Wrap(apiHandler)

	req := &http.Request{
		Method: "GET",
		URL:    &url.URL{Path: "/api/users"},
		Host:   "api.example.com",
		Header: http.Header{
			"Accept": []string{"application/json"},
		},
	}

	b.ResetTimer()
	b.ReportAllocs()

	for b.Loop() {
		rw := &mockResponseWriter{}
		httpHandler.ServeHTTP(rw, req)
	}
}
