package config

import (
	"testing"
)

func TestValidateConfigAdvanced(t *testing.T) {
	tests := []struct {
		name        string
		config      *Config
		expectValid bool
		expectError bool
	}{
		{
			name: "Valid config",
			config: &Config{
				SecretId:  "AKIDabcdefghijklmnopqrstuvwxyz123",
				SecretKey: "abcdefghijklmnopqrstuvwxyz1234567890",
				Bucket:    "test-bucket-123",
				Region:    "ap-beijing",
			},
			expectValid: true,
			expectError: false,
		},
		{
			name: "Invalid SecretId",
			config: &Config{
				SecretId:  "invalid",
				SecretKey: "abcdefghijklmnopqrstuvwxyz1234567890",
				Bucket:    "test-bucket-123",
				Region:    "ap-beijing",
			},
			expectValid: false,
			expectError: true,
		},
		{
			name: "Invalid Bucket name",
			config: &Config{
				SecretId:  "AKIDabcdefghijklmnopqrstuvwxyz123",
				SecretKey: "abcdefghijklmnopqrstuvwxyz1234567890",
				Bucket:    "Invalid-Bucket",
				Region:    "ap-beijing",
			},
			expectValid: false,
			expectError: true,
		},
		{
			name: "Unsupported region",
			config: &Config{
				SecretId:  "AKIDabcdefghijklmnopqrstuvwxyz123",
				SecretKey: "abcdefghijklmnopqrstuvwxyz1234567890",
				Bucket:    "test-bucket-123",
				Region:    "us-invalid",
			},
			expectValid: false,
			expectError: true,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			result := ValidateConfigAdvanced(tt.config)

			if result.Valid != tt.expectValid {
				t.Errorf("ValidateConfigAdvanced() valid = %v, want %v", result.Valid, tt.expectValid)
			}

			if tt.expectError && len(result.Errors) == 0 {
				t.Error("Expected errors but got none")
			}

			if !tt.expectError && len(result.Errors) > 0 {
				t.Errorf("Unexpected errors: %v", result.Errors)
			}
		})
	}
}

func TestIsValidSecretId(t *testing.T) {
	tests := []struct {
		name     string
		secretId string
		valid    bool
	}{
		{
			name:     "Valid SecretId",
			secretId: "AKIDabcdefghijklmnopqrstuvwxyz123",
			valid:    true,
		},
		{
			name:     "Too short",
			secretId: "short",
			valid:    false,
		},
		{
			name:     "Too long",
			secretId: "verylongsecretidthatiswaytoolongfortencentcloudvalidationtest",
			valid:    false,
		},
		{
			name:     "Invalid characters",
			secretId: "AKID@invalid#chars",
			valid:    false,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			result := isValidSecretId(tt.secretId)
			if result != tt.valid {
				t.Errorf("isValidSecretId(%s) = %v, want %v", tt.secretId, result, tt.valid)
			}
		})
	}
}

func TestIsValidSecretKey(t *testing.T) {
	tests := []struct {
		name      string
		secretKey string
		valid     bool
	}{
		{
			name:      "Valid SecretKey",
			secretKey: "abcdefghijklmnopqrstuvwxyz1234567890",
			valid:     true,
		},
		{
			name:      "Too short",
			secretKey: "short",
			valid:     false,
		},
		{
			name:      "Invalid characters",
			secretKey: "invalid@key#chars",
			valid:     false,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			result := isValidSecretKey(tt.secretKey)
			if result != tt.valid {
				t.Errorf("isValidSecretKey(%s) = %v, want %v", tt.secretKey, result, tt.valid)
			}
		})
	}
}

func TestIsValidBucketName(t *testing.T) {
	tests := []struct {
		name   string
		bucket string
		valid  bool
	}{
		{
			name:   "Valid bucket",
			bucket: "test-bucket-123",
			valid:  true,
		},
		{
			name:   "Too short",
			bucket: "ab",
			valid:  false,
		},
		{
			name:   "Too long",
			bucket: "very-long-bucket-name-that-exceeds-the-maximum-length-limit-for-validation",
			valid:  false,
		},
		{
			name:   "Invalid characters",
			bucket: "Invalid_Bucket",
			valid:  false,
		},
		{
			name:   "Starts with dash",
			bucket: "-invalid",
			valid:  false,
		},
		{
			name:   "Ends with dash",
			bucket: "invalid-",
			valid:  false,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			result := isValidBucketName(tt.bucket)
			if result != tt.valid {
				t.Errorf("isValidBucketName(%s) = %v, want %v", tt.bucket, result, tt.valid)
			}
		})
	}
}

func TestIsSupportedRegion(t *testing.T) {
	supportedRegions := getSupportedRegions()

	tests := []struct {
		name      string
		region    string
		supported bool
	}{
		{
			name:      "Supported region Beijing",
			region:    "ap-beijing",
			supported: true,
		},
		{
			name:      "Supported region Shanghai",
			region:    "ap-shanghai",
			supported: true,
		},
		{
			name:      "Unsupported region",
			region:    "us-invalid",
			supported: false,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			result := isSupportedRegion(tt.region, supportedRegions)
			if result != tt.supported {
				t.Errorf("isSupportedRegion(%s) = %v, want %v", tt.region, result, tt.supported)
			}
		})
	}
}

func TestFormatValidationResult(t *testing.T) {
	tests := []struct {
		name   string
		result *ValidationResult
	}{
		{
			name: "Valid result",
			result: &ValidationResult{
				Valid:    true,
				Errors:   []string{},
				Warnings: []string{"Test warning"},
			},
		},
		{
			name: "Invalid result",
			result: &ValidationResult{
				Valid:    false,
				Errors:   []string{"Test error 1", "Test error 2"},
				Warnings: []string{},
			},
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			formatted := FormatValidationResult(tt.result)

			if formatted == "" {
				t.Error("Formatted result should not be empty")
			}

			if tt.result.Valid && !contains(formatted, "✅") {
				t.Error("Valid result should contain success indicator")
			}

			if !tt.result.Valid && !contains(formatted, "❌") {
				t.Error("Invalid result should contain error indicator")
			}

			if len(tt.result.Errors) > 0 && !contains(formatted, "🚨") {
				t.Error("Result with errors should contain error indicator")
			}

			if len(tt.result.Warnings) > 0 && !contains(formatted, "⚠️") {
				t.Error("Result with warnings should contain warning indicator")
			}
		})
	}
}

// 辅助函数
func contains(s, substr string) bool {
	return len(s) >= len(substr) && (s == substr || len(s) > 0 &&
		(hasPrefix(s, substr) || hasSuffix(s, substr) || contains(s[1:], substr)))
}

func hasPrefix(s, prefix string) bool {
	return len(s) >= len(prefix) && s[0:len(prefix)] == prefix
}

func hasSuffix(s, suffix string) bool {
	return len(s) >= len(suffix) && s[len(s)-len(suffix):] == suffix
}
