package config

import (
	"testing"
)

func TestNormalizeConfigDefaults_SetsPipelineDefaults(t *testing.T) {
	cfg := &GlobalConfig{}

	if err := NormalizeConfigDefaults(cfg); err != nil {
		t.Fatalf("NormalizeConfigDefaults() error = %v", err)
	}

	if !cfg.PipelineDefaults.EnableBackfillBatchMode {
		t.Fatal("PipelineDefaults.EnableBackfillBatchMode = false, want true")
	}
}

func TestGetBizTypeByServicePlanEssentialV2(t *testing.T) {
	cfg := O11yGlobalServerConfig{
		BizType: "dev-tidbcloud",
		BizTypeConfigs: map[string]string{
			"dedicated":    "dev-tidbcloud",
			"essential_v2": "dev-tidbcloud-nextgen",
		},
	}
	if got := cfg.GetBizTypeByServicePlan(" Essential_V2 "); got != "dev-tidbcloud-nextgen" {
		t.Fatalf("GetBizTypeByServicePlan() = %q, want dev-tidbcloud-nextgen", got)
	}

	delete(cfg.BizTypeConfigs, "essential_v2")
	if got := cfg.GetBizTypeByServicePlan("Essential_V2"); got != "" {
		t.Fatalf("GetBizTypeByServicePlan() = %q, want empty without explicit Essential V2 mapping", got)
	}
}

func TestRegionalExecutorConfig_GetPipelineDataplaneServerAddr(t *testing.T) {
	tests := []struct {
		name                string
		config              RegionalExecutorConfig
		pipelineId          uint64
		provider            string
		region              string
		expectedResult      string
		expectedDescription string
	}{
		{
			name: "pipeline is globally managed - should return empty string",
			config: RegionalExecutorConfig{
				GlobalManagedPipeline: []string{"123", "456", "789"},
				Servers: map[string]string{
					"us-west-1": "server1.example.com",
					"us-east-1": "server2.example.com",
				},
			},
			pipelineId:          123,
			provider:            "aws",
			region:              "us-west-1",
			expectedResult:      "",
			expectedDescription: "globally managed pipeline should return empty string regardless of region",
		},
		{
			name: "pipeline not globally managed and region exists - should return server address",
			config: RegionalExecutorConfig{
				GlobalManagedPipeline: []string{"456", "789"},
				Servers: map[string]string{
					"us-west-1": "server1.example.com",
					"us-east-1": "server2.example.com",
					"eu-west-1": "server3.example.com",
				},
			},
			pipelineId:          123,
			provider:            "aws",
			region:              "us-west-1",
			expectedResult:      "server1.example.com",
			expectedDescription: "should return correct server address for existing region",
		},
		{
			name: "provider-qualified key should win over bare region fallback",
			config: RegionalExecutorConfig{
				GlobalManagedPipeline: []string{"456", "789"},
				Servers: map[string]string{
					"ap-southeast-1":          "aws-server.example.com",
					"alicloud-ap-southeast-1": "alicloud-server.example.com",
				},
			},
			pipelineId:          123,
			provider:            "ALIBABACLOUD",
			region:              "ap-southeast-1",
			expectedResult:      "alicloud-server.example.com",
			expectedDescription: "provider-qualified config should avoid cross-cloud region collisions",
		},
		{
			name: "pipeline not globally managed but provider-specific region not found - should fall back to bare region",
			config: RegionalExecutorConfig{
				GlobalManagedPipeline: []string{"456", "789"},
				Servers: map[string]string{
					"ap-south-1": "fallback-server.example.com",
				},
			},
			pipelineId:          123,
			provider:            "azure",
			region:              "ap-south-1",
			expectedResult:      "fallback-server.example.com",
			expectedDescription: "legacy region-only keys should keep working",
		},
		{
			name: "pipeline not globally managed but region not found - should return empty string",
			config: RegionalExecutorConfig{
				GlobalManagedPipeline: []string{"456", "789"},
				Servers: map[string]string{
					"us-west-1": "server1.example.com",
					"us-east-1": "server2.example.com",
				},
			},
			pipelineId:          123,
			provider:            "aws",
			region:              "ap-south-1",
			expectedResult:      "",
			expectedDescription: "should return empty string when region is not found",
		},
		{
			name: "empty global managed pipeline list - should check servers",
			config: RegionalExecutorConfig{
				GlobalManagedPipeline: []string{},
				Servers: map[string]string{
					"us-west-1": "server1.example.com",
					"us-east-1": "server2.example.com",
				},
			},
			pipelineId:          123,
			provider:            "aws",
			region:              "us-east-1",
			expectedResult:      "server2.example.com",
			expectedDescription: "with empty global managed list, should return server address",
		},
		{
			name: "nil global managed pipeline list - should check servers",
			config: RegionalExecutorConfig{
				GlobalManagedPipeline: nil,
				Servers: map[string]string{
					"us-west-1": "server1.example.com",
					"us-east-1": "server2.example.com",
				},
			},
			pipelineId:          123,
			provider:            "aws",
			region:              "us-west-1",
			expectedResult:      "server1.example.com",
			expectedDescription: "with nil global managed list, should return server address",
		},
		{
			name: "empty servers map - should return empty string",
			config: RegionalExecutorConfig{
				GlobalManagedPipeline: []string{"456"},
				Servers:               map[string]string{},
			},
			pipelineId:          123,
			provider:            "aws",
			region:              "us-west-1",
			expectedResult:      "",
			expectedDescription: "with empty servers map, should return empty string",
		},
		{
			name: "nil servers map - should return empty string",
			config: RegionalExecutorConfig{
				GlobalManagedPipeline: []string{"456"},
				Servers:               nil,
			},
			pipelineId:          123,
			provider:            "aws",
			region:              "us-west-1",
			expectedResult:      "",
			expectedDescription: "with nil servers map, should return empty string",
		},
		{
			name: "pipeline id as string match - should be globally managed",
			config: RegionalExecutorConfig{
				GlobalManagedPipeline: []string{"123", "456"},
				Servers: map[string]string{
					"us-west-1": "server1.example.com",
				},
			},
			pipelineId:          123,
			provider:            "aws",
			region:              "us-west-1",
			expectedResult:      "",
			expectedDescription: "pipeline id string conversion should work correctly",
		},
		{
			name: "large pipeline id - should work correctly",
			config: RegionalExecutorConfig{
				GlobalManagedPipeline: []string{"9223372036854775807"}, // max int64
				Servers: map[string]string{
					"us-west-1": "server1.example.com",
				},
			},
			pipelineId:          9223372036854775807,
			provider:            "aws",
			region:              "us-west-1",
			expectedResult:      "",
			expectedDescription: "should handle large pipeline ids correctly",
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			result := tt.config.GetPipelineDataplaneServerAddr(tt.pipelineId, tt.provider, tt.region)
			if result != tt.expectedResult {
				t.Errorf("GetPipelineDataplaneServerAddr() = %v, want %v. %s",
					result, tt.expectedResult, tt.expectedDescription)
			}
		})
	}
}

func TestRegionalExecutorConfig_GetPipelineDataplaneServerAddr_EdgeCases(t *testing.T) {
	t.Run("zero pipeline id", func(t *testing.T) {
		config := RegionalExecutorConfig{
			GlobalManagedPipeline: []string{"0"},
			Servers: map[string]string{
				"us-west-1": "server1.example.com",
			},
		}
		result := config.GetPipelineDataplaneServerAddr(0, "aws", "us-west-1")
		if result != "" {
			t.Errorf("Expected empty string for globally managed pipeline id 0, got %v", result)
		}
	})

	t.Run("empty region string", func(t *testing.T) {
		config := RegionalExecutorConfig{
			GlobalManagedPipeline: []string{"456"},
			Servers: map[string]string{
				"":          "empty-region-server.example.com",
				"us-west-1": "server1.example.com",
			},
		}
		result := config.GetPipelineDataplaneServerAddr(123, "", "")
		if result != "empty-region-server.example.com" {
			t.Errorf("Expected server for empty region, got %v", result)
		}
	})

	t.Run("special characters in region", func(t *testing.T) {
		config := RegionalExecutorConfig{
			GlobalManagedPipeline: []string{"456"},
			Servers: map[string]string{
				"us-west-1@special": "special-server.example.com",
			},
		}
		result := config.GetPipelineDataplaneServerAddr(123, "aws", "us-west-1@special")
		if result != "special-server.example.com" {
			t.Errorf("Expected server for special region name, got %v", result)
		}
	})
}

func TestRegionalExecutorConfig_ProviderAwareLookups(t *testing.T) {
	config := RegionalExecutorConfig{
		Servers: map[string]string{
			"alicloud-ap-southeast-1": "https://aliyun-rs.example.com",
			"ap-southeast-1":          "https://legacy-rs.example.com",
		},
		PipelineImageOverride: map[string]string{
			"alicloud-ap-southeast-1": "aliyun/pipeline",
			"ap-southeast-1":          "legacy/pipeline",
		},
		PrometheusQueryEndpoints: map[string]string{
			"alicloud-ap-southeast-1": "aliyun.prom.example.com",
			"ap-southeast-1":          "legacy.prom.example.com",
		},
	}

	if got := config.GetServerAddr("aliyun", "ap-southeast-1"); got != "https://aliyun-rs.example.com" {
		t.Fatalf("GetServerAddr() got %q", got)
	}
	if got := config.GetPipelineImageOverride("ALIBABACLOUD", "ap-southeast-1"); got != "aliyun/pipeline" {
		t.Fatalf("GetPipelineImageOverride() got %q", got)
	}
	if got := config.GetPrometheusQueryEndpoint("alicloud", "ap-southeast-1"); got != "aliyun.prom.example.com" {
		t.Fatalf("GetPrometheusQueryEndpoint() got %q", got)
	}
	if got := config.GetPrometheusQueryEndpoint("", "ap-southeast-1"); got != "legacy.prom.example.com" {
		t.Fatalf("GetPrometheusQueryEndpoint() legacy fallback got %q", got)
	}
}
