package otel

import (
	"context"
	"testing"
	"time"
)

// TestConnectionRecovery 演示连接恢复机制的工作方式
func TestConnectionRecovery(t *testing.T) {
	// 创建测试配置（指向不存在的地址，模拟连接失败）
	config := &Config{
		ServiceName:       "test-service",
		CollectorURL:      "localhost:9999", // 不存在的端口
		Insecure:          true,
		Compressor:        "gzip",
		SampleRate:        1.0,
		Timeout:           2 * time.Second,
		RetryEnabled:      true,
		RetryInitInterval: 100 * time.Millisecond, // 测试用的短延迟
		RetryMaxInterval:  1 * time.Second,
		RetryMaxElapsed:   5 * time.Second,
	}

	// 初始化 OTel（会启动恢复管理器）
	err := InitWithConfig(config)
	if err != nil {
		t.Logf("初始化 OTel 时出现预期错误: %v", err)
		// 这是预期的，因为连接器会尝试连接到不存在的地址
	}

	// 获取恢复管理器
	rm := GetRecoveryManager()
	if rm == nil {
		t.Fatal("恢复管理器未初始化")
	}

	// 调整检查间隔为更短的时间便于测试
	rm.SetCheckInterval(1 * time.Second)

	// 等待几次检查周期
	time.Sleep(3 * time.Second)

	// 检查状态
	status := rm.GetConnectionStatus()
	t.Logf("连接状态: %s", status)

	// 验证连接失败被记录
	if rm.IsConnected() {
		t.Log("预期：连接应该失败（因为指向不存在的地址）")
	}

	// 清理
	_ = Shutdown(context.Background())
	Reset()

	t.Log("连接恢复测试完成")
}

// TestHealthCheck 演示健康检查功能
func TestHealthCheck(t *testing.T) {
	config := &Config{
		ServiceName:       "health-check-test",
		CollectorURL:      "localhost:4317",
		Insecure:          true,
		Compressor:        "gzip",
		SampleRate:        1.0,
		Timeout:           2 * time.Second,
		RetryEnabled:      true,
		RetryInitInterval: 100 * time.Millisecond,
		RetryMaxInterval:  1 * time.Second,
		RetryMaxElapsed:   5 * time.Second,
	}

	// 初始化
	err := InitWithConfig(config)
	if err != nil {
		t.Logf("初始化出错（预期）: %v", err)
	}

	manager := GetCurrentManager()
	if manager == nil {
		t.Fatal("管理器未初始化")
	}

	// 进行健康检查
	ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
	defer cancel()

	err = manager.HealthCheck(ctx)
	// 由于连接器不可达，这应该返回错误
	t.Logf("健康检查结果: %v", err)

	// 清理
	_ = Shutdown(context.Background())
	Reset()

	t.Log("健康检查测试完成")
}

// TestConfigValidation 演示配置验证和默认值设置
func TestConfigValidation(t *testing.T) {
	// 测试最小配置
	config := &Config{
		ServiceName:  "test-service",
		CollectorURL: "localhost:4317",
	}

	// 验证并设置默认值
	err := config.ValidateAndSetDefaults()
	if err != nil {
		t.Fatalf("配置验证失败: %v", err)
	}

	// 验证默认值是否正确设置
	if config.Timeout != 10*time.Second {
		t.Errorf("期望 Timeout=10s, 得到 %v", config.Timeout)
	}
	if config.RetryInitInterval != 1*time.Second {
		t.Errorf("期望 RetryInitInterval=1s, 得到 %v", config.RetryInitInterval)
	}
	if config.RetryMaxInterval != 30*time.Second {
		t.Errorf("期望 RetryMaxInterval=30s, 得到 %v", config.RetryMaxInterval)
	}
	if config.RetryMaxElapsed != 5*time.Minute {
		t.Errorf("期望 RetryMaxElapsed=5m, 得到 %v", config.RetryMaxElapsed)
	}

	t.Log("配置验证测试通过")
}

// TestRetryConfiguration 演示自定义重试配置
func TestRetryConfiguration(t *testing.T) {
	config := &Config{
		ServiceName:       "custom-retry-test",
		CollectorURL:      "localhost:4317",
		Insecure:          true,
		Timeout:           15 * time.Second,
		RetryEnabled:      true,
		RetryInitInterval: 500 * time.Millisecond,
		RetryMaxInterval:  60 * time.Second,
		RetryMaxElapsed:   10 * time.Minute,
	}

	err := config.ValidateAndSetDefaults()
	if err != nil {
		t.Fatalf("配置验证失败: %v", err)
	}

	// 验证自定义值是否保留
	if config.Timeout != 15*time.Second {
		t.Errorf("自定义 Timeout 不正确")
	}
	if config.RetryInitInterval != 500*time.Millisecond {
		t.Errorf("自定义 RetryInitInterval 不正确")
	}

	t.Log("重试配置测试通过")
}

// TestRecoveryManagerStatus 演示恢复管理器的状态查询
func TestRecoveryManagerStatus(t *testing.T) {
	config := DefaultConfig()
	config.ServiceName = "status-test"
	config.CollectorURL = "collector:4317"

	err := InitWithConfig(config)
	if err != nil {
		t.Logf("初始化出错（预期）: %v", err)
	}

	rm := GetRecoveryManager()
	if rm == nil {
		t.Fatal("恢复管理器未初始化")
	}

	// 调整为快速检查便于测试
	rm.SetCheckInterval(500 * time.Millisecond)
	rm.SetMaxRetries(3)

	// 等待一个检查周期
	time.Sleep(1 * time.Second)

	// 获取状态
	status := rm.GetConnectionStatus()
	t.Logf("状态字符串: %s", status)

	isConnected := rm.IsConnected()
	t.Logf("连接状态: %v", isConnected)

	lastCheck := rm.GetLastCheckTime()
	t.Logf("最后检查时间: %v", lastCheck)

	// 测试重置功能
	rm.ResetRetryCount()
	status = rm.GetConnectionStatus()
	t.Logf("重置后的状态: %s", status)

	// 清理
	_ = Shutdown(context.Background())
	Reset()

	t.Log("恢复管理器状态测试完成")
}
