// Package http3 提供 HTTP/3 服务器功能的测试。
//
// 该文件测试 HTTP/3 服务器模块的各项功能，包括：
//   - 服务器创建和配置验证
//   - Alt-Svc 头部生成
//   - 服务器统计信息获取
//   - 运行状态检查
//   - 服务器停止和优雅停止
//
// 作者：xfy
package http3

import (
	"crypto/rand"
	"crypto/rsa"
	"crypto/tls"
	"crypto/x509"
	"crypto/x509/pkix"
	"encoding/pem"
	"math/big"
	"net"
	"testing"
	"time"

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

// TestNewServer_NilConfig 测试空配置错误
func TestNewServer_NilConfig(t *testing.T) {
	handler := func(_ *fasthttp.RequestCtx) {}

	server, err := NewServer(nil, handler, &tls.Config{})

	if err == nil {
		t.Error("Expected error for nil config")
	}
	if server != nil {
		t.Error("Expected nil server for nil config")
	}
	if err.Error() != "http3 config is nil" {
		t.Errorf("Expected error message 'http3 config is nil', got: %v", err)
	}
}

// TestNewServer_NilHandler 测试空 handler 错误
func TestNewServer_NilHandler(t *testing.T) {
	cfg := &config.HTTP3Config{
		Enabled:    true,
		Listen:     ":443",
		Enable0RTT: true,
	}

	server, err := NewServer(cfg, nil, &tls.Config{})

	if err == nil {
		t.Error("Expected error for nil handler")
	}
	if server != nil {
		t.Error("Expected nil server for nil handler")
	}
	if err.Error() != "handler is nil" {
		t.Errorf("Expected error message 'handler is nil', got: %v", err)
	}
}

// TestNewServer_NilTLS 测试空 TLS 配置错误
func TestNewServer_NilTLS(t *testing.T) {
	cfg := &config.HTTP3Config{
		Enabled:    true,
		Listen:     ":443",
		Enable0RTT: true,
	}
	handler := func(_ *fasthttp.RequestCtx) {}

	server, err := NewServer(cfg, handler, nil)

	if err == nil {
		t.Error("Expected error for nil TLS config")
	}
	if server != nil {
		t.Error("Expected nil server for nil TLS config")
	}
	if err.Error() != "tls config is required for HTTP/3" {
		t.Errorf("Expected error message 'tls config is required for HTTP/3', got: %v", err)
	}
}

// TestNewServer_Success 测试成功创建服务器
func TestNewServer_Success(t *testing.T) {
	cfg := &config.HTTP3Config{
		Enabled:    true,
		Listen:     ":443",
		Enable0RTT: true,
		MaxStreams: 100,
	}
	handler := func(_ *fasthttp.RequestCtx) {}
	tlsConfig := &tls.Config{
		Certificates: []tls.Certificate{},
	}

	server, err := NewServer(cfg, handler, tlsConfig)
	if err != nil {
		t.Errorf("Unexpected error: %v", err)
	}
	if server == nil {
		t.Fatal("Expected non-nil server")
	}

	if server.config != cfg {
		t.Error("Config not set correctly")
	}

	if server.handler == nil {
		t.Error("Handler not set correctly")
	}

	if server.adapter == nil {
		t.Error("Adapter not initialized")
	}

	if server.tlsConfig != tlsConfig {
		t.Error("TLS config not set correctly")
	}

	if server.running {
		t.Error("Server should not be running initially")
	}
}

// TestGetAltSvcHeader_DefaultPort 测试默认端口 Alt-Svc 头
func TestGetAltSvcHeader_DefaultPort(t *testing.T) {
	cfg := &config.HTTP3Config{
		Enabled: true,
		Listen:  ":443",
	}
	handler := func(_ *fasthttp.RequestCtx) {}

	server, _ := NewServer(cfg, handler, &tls.Config{})

	header := server.GetAltSvcHeader()

	expected := `h3=":443"; ma=86400`
	if header != expected {
		t.Errorf("Expected Alt-Svc header '%s', got '%s'", expected, header)
	}
}

// TestGetAltSvcHeader_CustomPort 测试自定义端口 Alt-Svc 头
func TestGetAltSvcHeader_CustomPort(t *testing.T) {
	cfg := &config.HTTP3Config{
		Enabled: true,
		Listen:  ":8443",
	}
	handler := func(_ *fasthttp.RequestCtx) {}

	server, _ := NewServer(cfg, handler, &tls.Config{})

	header := server.GetAltSvcHeader()

	expected := `h3=":8443"; ma=86400`
	if header != expected {
		t.Errorf("Expected Alt-Svc header '%s', got '%s'", expected, header)
	}
}

// TestGetAltSvcHeader_Disabled 测试禁用 HTTP/3 时返回空
func TestGetAltSvcHeader_Disabled(t *testing.T) {
	cfg := &config.HTTP3Config{
		Enabled: false,
		Listen:  ":443",
	}
	handler := func(_ *fasthttp.RequestCtx) {}

	server, _ := NewServer(cfg, handler, &tls.Config{})

	header := server.GetAltSvcHeader()

	if header != "" {
		t.Errorf("Expected empty Alt-Svc header when disabled, got '%s'", header)
	}
}

// TestGetAltSvcHeader_EmptyListen 测试空监听地址时使用默认端口
func TestGetAltSvcHeader_EmptyListen(t *testing.T) {
	cfg := &config.HTTP3Config{
		Enabled: true,
		Listen:  "", // 空，使用默认 :443
	}
	handler := func(_ *fasthttp.RequestCtx) {}

	server, _ := NewServer(cfg, handler, &tls.Config{})

	header := server.GetAltSvcHeader()

	expected := `h3=":443"; ma=86400`
	if header != expected {
		t.Errorf("Expected Alt-Svc header '%s', got '%s'", expected, header)
	}
}

// TestGetStats 测试获取统计信息
func TestGetStats(t *testing.T) {
	cfg := &config.HTTP3Config{
		Enabled:    true,
		Listen:     ":8443",
		Enable0RTT: true,
		MaxStreams: 200,
	}
	handler := func(_ *fasthttp.RequestCtx) {}

	server, _ := NewServer(cfg, handler, &tls.Config{})

	stats := server.GetStats()

	if stats.Running {
		t.Error("Expected Running to be false initially")
	}

	if stats.Listen != ":8443" {
		t.Errorf("Expected Listen ':8443', got '%s'", stats.Listen)
	}

	if !stats.Enable0RTT {
		t.Error("Expected Enable0RTT to be true")
	}

	if stats.MaxStreams != 200 {
		t.Errorf("Expected MaxStreams 200, got %d", stats.MaxStreams)
	}
}

// TestIsRunning 测试运行状态检查
func TestIsRunning(t *testing.T) {
	cfg := &config.HTTP3Config{
		Enabled: true,
		Listen:  ":443",
	}
	handler := func(_ *fasthttp.RequestCtx) {}

	server, _ := NewServer(cfg, handler, &tls.Config{})

	// 初始状态应该是 false
	if server.IsRunning() {
		t.Error("Expected IsRunning to be false initially")
	}

	// 手动设置运行状态（不启动真实服务器）
	server.mu.Lock()
	server.running = true
	server.mu.Unlock()

	if !server.IsRunning() {
		t.Error("Expected IsRunning to be true after setting")
	}

	// 再次设置为 false
	server.mu.Lock()
	server.running = false
	server.mu.Unlock()

	if server.IsRunning() {
		t.Error("Expected IsRunning to be false after unsetting")
	}
}

// TestStop_NotRunning 测试停止未运行的服务器
func TestStop_NotRunning(t *testing.T) {
	cfg := &config.HTTP3Config{
		Enabled: true,
		Listen:  ":443",
	}
	handler := func(_ *fasthttp.RequestCtx) {}

	server, _ := NewServer(cfg, handler, &tls.Config{})

	// 服务器未启动，Stop 应该返回 nil
	err := server.Stop()
	if err != nil {
		t.Errorf("Expected nil error when stopping non-running server, got: %v", err)
	}
}

// TestGracefulStop_NotRunning 测试优雅停止未运行的服务器
func TestGracefulStop_NotRunning(t *testing.T) {
	cfg := &config.HTTP3Config{
		Enabled: true,
		Listen:  ":443",
	}
	handler := func(_ *fasthttp.RequestCtx) {}

	server, _ := NewServer(cfg, handler, &tls.Config{})

	// 服务器未启动，GracefulStop 应该返回 nil
	err := server.GracefulStop(5 * time.Second)
	if err != nil {
		t.Errorf("Expected nil error when graceful stopping non-running server, got: %v", err)
	}
}

// TestGracefulStop_WithTimeout 测试优雅停止超时
func TestGracefulStop_WithTimeout(t *testing.T) {
	cfg := &config.HTTP3Config{
		Enabled: true,
		Listen:  ":443",
	}
	handler := func(_ *fasthttp.RequestCtx) {}

	server, _ := NewServer(cfg, handler, &tls.Config{})

	// 测试不同超时值
	tests := []struct {
		name    string
		timeout time.Duration
	}{
		{"zero timeout", 0},
		{"short timeout", 100 * time.Millisecond},
		{"long timeout", 30 * time.Second},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			err := server.GracefulStop(tt.timeout)
			if err != nil {
				t.Errorf("Unexpected error: %v", err)
			}
		})
	}
}

// TestServer_MultipleStop 测试多次调用 Stop
func TestServer_MultipleStop(t *testing.T) {
	cfg := &config.HTTP3Config{
		Enabled: true,
		Listen:  ":443",
	}
	handler := func(_ *fasthttp.RequestCtx) {}

	server, _ := NewServer(cfg, handler, &tls.Config{})

	// 多次调用 Stop 应该都是安全的
	for i := 0; i < 3; i++ {
		err := server.Stop()
		if err != nil {
			t.Errorf("Stop call %d returned error: %v", i+1, err)
		}
	}
}

// TestServer_MultipleGracefulStop 测试多次调用 GracefulStop
func TestServer_MultipleGracefulStop(t *testing.T) {
	cfg := &config.HTTP3Config{
		Enabled: true,
		Listen:  ":443",
	}
	handler := func(_ *fasthttp.RequestCtx) {}

	server, _ := NewServer(cfg, handler, &tls.Config{})

	// 多次调用 GracefulStop 应该都是安全的
	for i := 0; i < 3; i++ {
		err := server.GracefulStop(1 * time.Second)
		if err != nil {
			t.Errorf("GracefulStop call %d returned error: %v", i+1, err)
		}
	}
}

// TestGetAltSvcHeader_PortBoundaries 测试端口边界值
func TestGetAltSvcHeader_PortBoundaries(t *testing.T) {
	tests := []struct {
		name     string
		listen   string
		expected string
	}{
		{
			name:     "标准 HTTP 端口 80",
			listen:   ":80",
			expected: `h3=":80"; ma=86400`,
		},
		{
			name:     "标准 HTTPS 端口 443",
			listen:   ":443",
			expected: `h3=":443"; ma=86400`,
		},
		{
			name:     "高端口 65535",
			listen:   ":65535",
			expected: `h3=":65535"; ma=86400`,
		},
		{
			name:     "低端口 1",
			listen:   ":1",
			expected: `h3=":1"; ma=86400`,
		},
		{
			name:     "带 IP 地址的监听",
			listen:   "0.0.0.0:8443",
			expected: `h3=":0.0.0.0:8443"; ma=86400`,
		},
		{
			name:     "带 IPv6 地址的监听",
			listen:   "[::]:8443",
			expected: `h3=":[::]:8443"; ma=86400`,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			cfg := &config.HTTP3Config{
				Enabled: true,
				Listen:  tt.listen,
			}
			handler := func(_ *fasthttp.RequestCtx) {}

			server, _ := NewServer(cfg, handler, &tls.Config{})

			header := server.GetAltSvcHeader()
			if header != tt.expected {
				t.Errorf("GetAltSvcHeader() = %q, want %q", header, tt.expected)
			}
		})
	}
}

// TestGetAltSvcHeader_DisabledServer 测试禁用状态下的服务器
func TestGetAltSvcHeader_DisabledServer(t *testing.T) {
	cfg := &config.HTTP3Config{
		Enabled: false,
		Listen:  ":443",
	}
	handler := func(_ *fasthttp.RequestCtx) {}

	server, _ := NewServer(cfg, handler, &tls.Config{})

	header := server.GetAltSvcHeader()
	if header != "" {
		t.Errorf("Expected empty Alt-Svc header when disabled, got %q", header)
	}
}

// TestGetAltSvcHeader_NilConfig 测试 nil 配置情况
func TestGetAltSvcHeader_NilConfig(t *testing.T) {
	cfg := &config.HTTP3Config{
		Enabled: true,
		Listen:  ":443",
	}
	handler := func(_ *fasthttp.RequestCtx) {}

	server, _ := NewServer(cfg, handler, &tls.Config{})

	// 正常情况下应该返回 header
	header := server.GetAltSvcHeader()
	if header == "" {
		t.Error("Expected non-empty Alt-Svc header with valid config")
	}
}

// TestStart_AlreadyRunning 测试启动已运行的服务器
func TestStart_AlreadyRunning(t *testing.T) {
	cfg := &config.HTTP3Config{
		Enabled:    true,
		Listen:     ":0", // 使用随机端口避免冲突
		MaxStreams: 100,
	}
	handler := func(_ *fasthttp.RequestCtx) {}

	cert := generateTestCertificate(t)
	tlsConfig := &tls.Config{
		Certificates: []tls.Certificate{cert},
	}

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

	// 启动服务器
	err = server.Start()
	if err != nil {
		t.Fatalf("Failed to start server: %v", err)
	}
	defer server.Stop()

	// 再次启动应该失败
	err = server.Start()
	if err == nil {
		t.Error("Expected error when starting already running server")
	}
	if err.Error() != "server already running" {
		t.Errorf("Expected 'server already running' error, got: %v", err)
	}
}

// TestStart_InvalidListenAddress 测试无效监听地址
func TestStart_InvalidListenAddress(t *testing.T) {
	cfg := &config.HTTP3Config{
		Enabled:    true,
		Listen:     "invalid:address:format", // 无效地址
		MaxStreams: 100,
	}
	handler := func(_ *fasthttp.RequestCtx) {}
	tlsConfig := &tls.Config{
		Certificates: []tls.Certificate{},
	}

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

	err = server.Start()
	if err == nil {
		t.Error("Expected error for invalid listen address")
		server.Stop()
	}
}

// TestStop_RunningServer 测试停止运行中的服务器
func TestStop_RunningServer(t *testing.T) {
	cfg := &config.HTTP3Config{
		Enabled:    true,
		Listen:     ":0",
		MaxStreams: 100,
	}
	handler := func(_ *fasthttp.RequestCtx) {}

	cert := generateTestCertificate(t)
	tlsConfig := &tls.Config{
		Certificates: []tls.Certificate{cert},
	}

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

	// 启动服务器
	err = server.Start()
	if err != nil {
		t.Fatalf("Failed to start server: %v", err)
	}

	if !server.IsRunning() {
		t.Error("Server should be running after Start()")
	}

	// 停止服务器
	err = server.Stop()
	if err != nil {
		t.Errorf("Unexpected error stopping server: %v", err)
	}

	if server.IsRunning() {
		t.Error("Server should not be running after Stop()")
	}
}

// TestGracefulStop_RunningServer 测试优雅停止运行中的服务器
func TestGracefulStop_RunningServer(t *testing.T) {
	cfg := &config.HTTP3Config{
		Enabled:    true,
		Listen:     ":0",
		MaxStreams: 100,
	}
	handler := func(_ *fasthttp.RequestCtx) {}

	cert := generateTestCertificate(t)
	tlsConfig := &tls.Config{
		Certificates: []tls.Certificate{cert},
	}

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

	// 启动服务器
	err = server.Start()
	if err != nil {
		t.Fatalf("Failed to start server: %v", err)
	}

	if !server.IsRunning() {
		t.Error("Server should be running after Start()")
	}

	// 优雅停止服务器
	err = server.GracefulStop(5 * time.Second)
	if err != nil {
		t.Errorf("Unexpected error graceful stopping server: %v", err)
	}

	if server.IsRunning() {
		t.Error("Server should not be running after GracefulStop()")
	}
}

// TestStart_Enable0RTT 测试启用 0-RTT 时的警告日志
func TestStart_Enable0RTT(t *testing.T) {
	cfg := &config.HTTP3Config{
		Enabled:    true,
		Listen:     ":0",
		Enable0RTT: true,
		MaxStreams: 100,
	}
	handler := func(_ *fasthttp.RequestCtx) {}

	cert := generateTestCertificate(t)
	tlsConfig := &tls.Config{
		Certificates: []tls.Certificate{cert},
	}

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

	err = server.Start()
	if err != nil {
		t.Fatalf("Failed to start server: %v", err)
	}
	defer server.Stop()

	// 验证服务器已启动
	if !server.IsRunning() {
		t.Error("Server should be running")
	}
}

// TestStart_DefaultValues 测试默认值设置
func TestStart_DefaultValues(t *testing.T) {
	cfg := &config.HTTP3Config{
		Enabled:    true,
		Listen:     ":0",
		MaxStreams: 0, // 使用默认值
	}
	handler := func(_ *fasthttp.RequestCtx) {}

	cert := generateTestCertificate(t)
	tlsConfig := &tls.Config{
		Certificates: []tls.Certificate{cert},
	}

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

	err = server.Start()
	if err != nil {
		t.Fatalf("Failed to start server: %v", err)
	}
	defer server.Stop()

	if !server.IsRunning() {
		t.Error("Server should be running")
	}
}

// generateTestCertificate 生成用于测试的自签名证书
func generateTestCertificate(t *testing.T) tls.Certificate {
	t.Helper()

	// 使用 RSA 密钥生成自签名证书
	tmpl := &x509.Certificate{
		SerialNumber:          big.NewInt(1),
		Subject:               pkix.Name{CommonName: "localhost"},
		NotBefore:             time.Now(),
		NotAfter:              time.Now().Add(time.Hour),
		KeyUsage:              x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
		ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
		BasicConstraintsValid: true,
		DNSNames:              []string{"localhost"},
		IPAddresses:           []net.IP{net.ParseIP("127.0.0.1")},
	}

	priv, err := rsa.GenerateKey(rand.Reader, 2048)
	if err != nil {
		t.Fatalf("Failed to generate RSA key: %v", err)
	}

	certDER, err := x509.CreateCertificate(rand.Reader, tmpl, tmpl, &priv.PublicKey, priv)
	if err != nil {
		t.Fatalf("Failed to create certificate: %v", err)
	}

	certPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: certDER})
	keyPEM := pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)})

	cert, err := tls.X509KeyPair(certPEM, keyPEM)
	if err != nil {
		t.Fatalf("Failed to load certificate: %v", err)
	}

	return cert
}
