// Package http2 提供 HTTP/2 集成测试。
//
// 该文件包含 HTTP/2 的端到端集成测试：
//   - HTTP/2 请求处理
//   - ALPN 协商
//   - HTTP/1.1 fallback
//
// 运行方式: go test -tags=integration ./internal/http2/...
//
// 作者：xfy
package http2

import (
	"bytes"
	"net"
	"net/http"
	"net/http/httptest"
	"testing"
	"time"

	"github.com/valyala/fasthttp"
	"rua.plus/lolly/internal/config"
)

// TestIntegrationHTTP2Request 测试 HTTP/2 请求处理（需要 TLS 证书）。
func TestIntegrationHTTP2Request(t *testing.T) {
	// 跳过集成测试，除非显式启用
	if testing.Short() {
		t.Skip("Skipping integration test in short mode")
	}

	// 注意：这需要有效的 TLS 证书才能完整测试
	// 这里使用非 TLS 模式测试基本功能

	handler := func(ctx *fasthttp.RequestCtx) {
		ctx.WriteString("Hello HTTP/2")
		ctx.SetStatusCode(fasthttp.StatusOK)
	}

	cfg := &config.HTTP2Config{
		Enabled:              true,
		MaxConcurrentStreams: 100,
	}

	server, err := NewServer(cfg, handler, nil)
	if err != nil {
		t.Fatalf("Failed to create server: %v", err)
	}

	// 创建监听器
	ln, err := net.Listen("tcp", "127.0.0.1:0")
	if err != nil {
		t.Fatalf("Failed to create listener: %v", err)
	}
	defer func() {
		if err := ln.Close(); err != nil {
			t.Logf("Failed to close listener: %v", err)
		}
	}()

	// 启动服务器（在后台）
	go func() {
		if err := server.Serve(ln); err != nil {
			t.Logf("Server serve error: %v", err)
		}
	}()

	// 等待服务器启动
	time.Sleep(100 * time.Millisecond)

	// 停止服务器
	if err := server.Stop(); err != nil {
		t.Errorf("Failed to stop server: %v", err)
	}
}

// TestIntegrationHTTP1Fallback 测试 HTTP/1.1 回退。
func TestIntegrationHTTP1Fallback(t *testing.T) {
	if testing.Short() {
		t.Skip("Skipping integration test in short mode")
	}

	handler := func(ctx *fasthttp.RequestCtx) {
		ctx.WriteString("Fallback to HTTP/1.1")
		ctx.SetStatusCode(fasthttp.StatusOK)
	}

	cfg := &config.HTTP2Config{
		Enabled:              true,
		MaxConcurrentStreams: 100,
	}

	server, err := NewServer(cfg, handler, nil)
	if err != nil {
		t.Fatalf("Failed to create server: %v", err)
	}

	// 验证服务器支持 HTTP/1.1 回退
	if server.handler == nil {
		t.Error("Server handler should be set for HTTP/1.1 fallback")
	}
}

// TestIntegrationConcurrentStreams 测试并发流处理。
func TestIntegrationConcurrentStreams(t *testing.T) {
	if testing.Short() {
		t.Skip("Skipping integration test in short mode")
	}

	requestCount := 0
	handler := func(ctx *fasthttp.RequestCtx) {
		requestCount++
		ctx.WriteString("OK")
		ctx.SetStatusCode(fasthttp.StatusOK)
	}

	cfg := &config.HTTP2Config{
		Enabled:              true,
		MaxConcurrentStreams: 10,
	}

	server, err := NewServer(cfg, handler, nil)
	if err != nil {
		t.Fatalf("Failed to create server: %v", err)
	}

	// 验证并发流限制
	if server.http2Server.MaxConcurrentStreams != 10 {
		t.Errorf("Expected MaxConcurrentStreams 10, got %d",
			server.http2Server.MaxConcurrentStreams)
	}
}

// TestIntegrationAdapterConversion 测试适配器转换。
func TestIntegrationAdapterConversion(t *testing.T) {
	handler := func(ctx *fasthttp.RequestCtx) {
		// 设置响应头和体
		ctx.Response.Header.Set("X-Custom-Header", "test-value")
		ctx.WriteString("Converted response")
		ctx.SetStatusCode(fasthttp.StatusOK)
	}

	adapter := NewFastHTTPHandlerAdapter(handler)

	// 创建标准 HTTP 请求
	req, err := http.NewRequest(http.MethodGet, "http://example.com/test", nil)
	if err != nil {
		t.Fatalf("Failed to create request: %v", err)
	}
	req.Header.Set("Accept", "application/json")

	// 使用 httptest 记录响应
	recorder := &testResponseRecorder{
		header: make(http.Header),
	}

	// 执行适配器
	adapter.ServeHTTP(recorder, req)

	// 验证响应
	if recorder.statusCode != http.StatusOK {
		t.Errorf("Expected status %d, got %d", http.StatusOK, recorder.statusCode)
	}

	if recorder.body.String() != "Converted response" {
		t.Errorf("Expected body 'Converted response', got '%s'", recorder.body.String())
	}
}

type testResponseRecorder struct {
	header     http.Header
	body       testBuffer
	statusCode int
}

func (r *testResponseRecorder) Header() http.Header {
	return r.header
}

func (r *testResponseRecorder) Write(p []byte) (int, error) {
	return r.body.Write(p)
}

func (r *testResponseRecorder) WriteHeader(code int) {
	r.statusCode = code
}

// testBuffer 是一个简单的字节缓冲区。
type testBuffer struct {
	data []byte
}

func (b *testBuffer) Write(p []byte) (int, error) {
	b.data = append(b.data, p...)
	return len(p), nil
}

func (b *testBuffer) String() string {
	return string(b.data)
}

// BenchmarkAdapterConversion 基准测试适配器转换性能。
func BenchmarkAdapterConversion(b *testing.B) {
	handler := func(ctx *fasthttp.RequestCtx) {
		ctx.WriteString("Hello")
		ctx.SetStatusCode(fasthttp.StatusOK)
	}

	adapter := NewFastHTTPHandlerAdapter(handler)
	req := httptest.NewRequest(http.MethodGet, "/test", nil)
	rec := httptest.NewRecorder()

	b.ResetTimer()
	b.ReportAllocs()

	for b.Loop() {
		rec.Body.Reset()
		adapter.ServeHTTP(rec, req)
	}
}

// BenchmarkAdapterWithBody 基准测试带请求体的适配器。
func BenchmarkAdapterWithBody(b *testing.B) {
	handler := func(ctx *fasthttp.RequestCtx) {
		ctx.Write(ctx.PostBody())
		ctx.SetStatusCode(fasthttp.StatusOK)
	}

	adapter := NewFastHTTPHandlerAdapter(handler)
	body := []byte(`{"test":"data","number":12345}`)

	b.ResetTimer()
	b.ReportAllocs()

	for b.Loop() {
		req := httptest.NewRequest(http.MethodPost, "/api", bytes.NewReader(body))
		rec := httptest.NewRecorder()
		adapter.ServeHTTP(rec, req)
	}
}

// BenchmarkServerCreation 基准测试服务器创建。
func BenchmarkServerCreation(b *testing.B) {
	cfg := &config.HTTP2Config{
		Enabled:              true,
		MaxConcurrentStreams: 100,
	}
	handler := func(_ *fasthttp.RequestCtx) {}

	b.ResetTimer()
	b.ReportAllocs()

	for b.Loop() {
		_, err := NewServer(cfg, handler, nil)
		if err != nil {
			b.Fatal(err)
		}
	}
}
