package cert

import (
	"testing"
	"time"

	v1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1"
	"github.com/tidbcloud/cluster-service-ng/domain/entity"
)

func TestCertSecret(t *testing.T) {
	tests := []struct {
		name     string
		compType string
		compId   string
		expected string
	}{
		{
			name:     "pd component",
			compType: "pd",
			compId:   "test123",
			expected: "db-test123-pd-cluster-secret",
		},
		{
			name:     "tidb component",
			compType: "tidb",
			compId:   "cluster1",
			expected: "db-cluster1-tidb-cluster-secret",
		},
		{
			name:     "tikv component",
			compType: "tikv",
			compId:   "prod",
			expected: "db-prod-tikv-cluster-secret",
		},
		{
			name:     "empty component id",
			compType: "pd",
			compId:   "",
			expected: "db-pd-cluster-secret",
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			result := certSecret(tt.compType, tt.compId)
			if result != tt.expected {
				t.Errorf("certSecret() = %v, want %v", result, tt.expected)
			}
		})
	}
}

func TestServerCertSecret(t *testing.T) {
	tests := []struct {
		name     string
		compType string
		compId   string
		expected string
	}{
		{
			name:     "with component id",
			compType: "tidb",
			compId:   "test123",
			expected: "db-test123-tidb-server-secret",
		},
		{
			name:     "empty component id",
			compType: "tidb",
			compId:   "",
			expected: "db-tidb-server-secret",
		},
		{
			name:     "pd component",
			compType: "pd",
			compId:   "cluster1",
			expected: "db-cluster1-pd-server-secret",
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			result := ServerCertSecret(tt.compType, tt.compId)
			if result != tt.expected {
				t.Errorf("ServerCertSecret() = %v, want %v", result, tt.expected)
			}
		})
	}
}

func TestClientCertSecret(t *testing.T) {
	result := clientCertSecret()
	expected := "db-cluster-client-secret"
	if result != expected {
		t.Errorf("clientCertSecret() = %v, want %v", result, expected)
	}
}

func TestDnsNameWildcard(t *testing.T) {
	tests := []struct {
		name      string
		compType  string
		compId    string
		namespace string
		expected  []string
	}{
		{
			name:      "pd component",
			compType:  "pd",
			compId:    "test123",
			namespace: "default",
			expected: []string{
				"*.db-cluster",
				"*.db-cluster.default",
				"*.db-cluster.default.svc",
				"*.db-cluster.default.svc.cluster.local",
				"db-test123-pd",
				"db-test123-pd.default",
				"db-test123-pd.default.svc",
				"db-test123-pd.default.svc.cluster.local",
				"db-test123-pd-peer",
				"db-test123-pd-peer.default",
				"db-test123-pd-peer.default.svc",
				"db-test123-pd-peer.default.svc.cluster.local",
				"*.db-test123-pd-peer",
				"*.db-test123-pd-peer.default",
				"*.db-test123-pd-peer.default.svc",
				"*.db-test123-pd-peer.default.svc.cluster.local",
				"db-pd",
				"db-pd.default",
				"db-pd.default.svc",
				"db-pd.default.svc.cluster.local",
			},
		},
		{
			name:      "tidb component",
			compType:  "tidb",
			compId:    "cluster1",
			namespace: "prod",
			expected: []string{
				"*.db-cluster",
				"*.db-cluster.prod",
				"*.db-cluster.prod.svc",
				"*.db-cluster.prod.svc.cluster.local",
				"db-cluster1-tidb",
				"db-cluster1-tidb.prod",
				"db-cluster1-tidb.prod.svc",
				"db-cluster1-tidb.prod.svc.cluster.local",
				"db-cluster1-tidb-peer",
				"db-cluster1-tidb-peer.prod",
				"db-cluster1-tidb-peer.prod.svc",
				"db-cluster1-tidb-peer.prod.svc.cluster.local",
				"*.db-cluster1-tidb-peer",
				"*.db-cluster1-tidb-peer.prod",
				"*.db-cluster1-tidb-peer.prod.svc",
				"*.db-cluster1-tidb-peer.prod.svc.cluster.local",
			},
		},
		{
			name:      "tikv component with empty id",
			compType:  "tikv",
			compId:    "",
			namespace: "staging",
			expected: []string{
				"*.db-cluster",
				"*.db-cluster.staging",
				"*.db-cluster.staging.svc",
				"*.db-cluster.staging.svc.cluster.local",
			},
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			result := dnsNameWildcard(tt.compType, tt.compId, tt.namespace)

			// Check lengths first
			if len(result) != len(tt.expected) {
				t.Errorf("dnsNameWildcard() returned %d names, want %d", len(result), len(tt.expected))
				t.Logf("Got: %v", result)
				t.Logf("Expected: %v", tt.expected)
				return
			}

			// Check that all expected names are present
			for _, expectedName := range tt.expected {
				found := false
				for _, actualName := range result {
					if actualName == expectedName {
						found = true
						break
					}
				}
				if !found {
					t.Errorf("dnsNameWildcard() missing expected name: %s", expectedName)
				}
			}
		})
	}
}

func TestGetTiDBClusterServerDNSWildcard(t *testing.T) {
	tests := []struct {
		name      string
		namespace string
		expected  []string
	}{
		{
			name:      "default namespace",
			namespace: "default",
			expected: []string{
				"*.default",
				"*.default.svc",
				"*.db-cluster",
				"*.db-cluster.default",
				"*.db-cluster.default.svc",
				"*.db-cluster.default.svc.cluster.local",
			},
		},
		{
			name:      "prod namespace",
			namespace: "prod",
			expected: []string{
				"*.prod",
				"*.prod.svc",
				"*.db-cluster",
				"*.db-cluster.prod",
				"*.db-cluster.prod.svc",
				"*.db-cluster.prod.svc.cluster.local",
			},
		},
	}

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

			if len(result) != len(tt.expected) {
				t.Errorf("getTiDBClusterServerDNSWildcard() returned %d names, want %d", len(result), len(tt.expected))
			}

			// Check that all expected names are present
			for _, expectedName := range tt.expected {
				found := false
				for _, actualName := range result {
					if actualName == expectedName {
						found = true
						break
					}
				}
				if !found {
					t.Errorf("getTiDBClusterServerDNSWildcard() missing expected name: %s", expectedName)
				}
			}
		})
	}
}

func TestGetTiProxyClusterServerDNSWildcard(t *testing.T) {
	tests := []struct {
		name         string
		compId       string
		namespace    string
		identity     string
		domainSuffix string
		expected     []string
	}{
		{
			name:         "with component id and identity",
			compId:       "test123",
			namespace:    "default",
			identity:     "identity1",
			domainSuffix: "example.com",
			expected: []string{
				"db-test123-tiproxy",
				"db-test123-tiproxy.default",
				"db-test123-tiproxy.default.svc",
				"db-test123-tiproxy.default.svc.cluster.local",
				"*.identity1.example.com",
			},
		},
		{
			name:         "empty component id",
			compId:       "",
			namespace:    "prod",
			identity:     "prod-identity",
			domainSuffix: "test.com",
			expected: []string{
				"db--tiproxy",
				"db--tiproxy.prod",
				"db--tiproxy.prod.svc",
				"db--tiproxy.prod.svc.cluster.local",
				"*.prod-identity.test.com",
			},
		},
		{
			name:         "no identity",
			compId:       "cluster1",
			namespace:    "test",
			identity:     "",
			domainSuffix: "example.org",
			expected: []string{
				"db-cluster1-tiproxy",
				"db-cluster1-tiproxy.test",
				"db-cluster1-tiproxy.test.svc",
				"db-cluster1-tiproxy.test.svc.cluster.local",
			},
		},
		{
			name:         "empty identity and domain suffix",
			compId:       "cluster2",
			namespace:    "staging",
			identity:     "",
			domainSuffix: "",
			expected: []string{
				"db-cluster2-tiproxy",
				"db-cluster2-tiproxy.staging",
				"db-cluster2-tiproxy.staging.svc",
				"db-cluster2-tiproxy.staging.svc.cluster.local",
			},
		},
		{
			name:         "only identity without domain",
			compId:       "test456",
			namespace:    "dev",
			identity:     "dev-identity",
			domainSuffix: "",
			expected: []string{
				"db-test456-tiproxy",
				"db-test456-tiproxy.dev",
				"db-test456-tiproxy.dev.svc",
				"db-test456-tiproxy.dev.svc.cluster.local",
			},
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			result := getTiProxyClusterServerDNSWildcard(tt.compId, tt.namespace, tt.identity, tt.domainSuffix)

			if len(result) != len(tt.expected) {
				t.Errorf("getTiProxyClusterServerDNSWildcard() returned %d names, want %d", len(result), len(tt.expected))
				t.Logf("Got: %v", result)
				t.Logf("Expected: %v", tt.expected)
				return
			}

			// Check that all expected names are present
			for _, expectedName := range tt.expected {
				found := false
				for _, actualName := range result {
					if actualName == expectedName {
						found = true
						break
					}
				}
				if !found {
					t.Errorf("getTiProxyClusterServerDNSWildcard() missing expected name: %s", expectedName)
				}
			}
		})
	}
}

func TestTiBRCertName(t *testing.T) {
	tests := []struct {
		name     string
		tibrName string
		expected string
	}{
		{
			name:     "simple name",
			tibrName: "backup1",
			expected: "backup1-tibr-cluster-secret",
		},
		{
			name:     "complex name",
			tibrName: "prod-backup-2024",
			expected: "prod-backup-2024-tibr-cluster-secret",
		},
		{
			name:     "empty name",
			tibrName: "",
			expected: "-tibr-cluster-secret",
		},
	}

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

func TestTibrDNSNames(t *testing.T) {
	tests := []struct {
		name      string
		tibrName  string
		namespace string
		expected  []string
	}{
		{
			name:      "simple backup",
			tibrName:  "backup1",
			namespace: "default",
			expected: []string{
				"backup1-tibr-headless",
				"backup1-tibr-headless.default",
				"backup1-tibr-headless.default.svc",
			},
		},
		{
			name:      "complex backup name",
			tibrName:  "prod-backup-2024",
			namespace: "production",
			expected: []string{
				"prod-backup-2024-tibr-headless",
				"prod-backup-2024-tibr-headless.production",
				"prod-backup-2024-tibr-headless.production.svc",
			},
		},
	}

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

			if len(result) != len(tt.expected) {
				t.Errorf("tibrDNSNames() returned %d names, want %d", len(result), len(tt.expected))
			}

			// Check that all expected names are present
			for _, expectedName := range tt.expected {
				found := false
				for _, actualName := range result {
					if actualName == expectedName {
						found = true
						break
					}
				}
				if !found {
					t.Errorf("tibrDNSNames() missing expected name: %s", expectedName)
				}
			}
		})
	}
}

func TestTidbDNSNameWildcard(t *testing.T) {
	tests := []struct {
		name      string
		namespace string
		expected  []string
	}{
		{
			name:      "default namespace",
			namespace: "default",
			expected: []string{
				"*.db-cluster",
				"*.db-cluster.default",
				"*.db-cluster.default.svc",
				"*.db-cluster.default.svc.cluster.local",
			},
		},
		{
			name:      "production namespace",
			namespace: "production",
			expected: []string{
				"*.db-cluster",
				"*.db-cluster.production",
				"*.db-cluster.production.svc",
				"*.db-cluster.production.svc.cluster.local",
			},
		},
	}

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

			if len(result) != len(tt.expected) {
				t.Errorf("tidbDNSNameWildcard() returned %d names, want %d", len(result), len(tt.expected))
			}

			for i, expected := range tt.expected {
				if result[i] != expected {
					t.Errorf("tidbDNSNameWildcard()[%d] = %v, want %v", i, result[i], expected)
				}
			}
		})
	}
}

func TestTiDBComponentCert(t *testing.T) {
	namespace := "test-namespace"
	cert := TiDBComponentCert(namespace)
	if cert == nil {
		t.Fatal("TiDBComponentCert() returned nil")
	}

	if cert.Namespace != namespace {
		t.Errorf("TiDBComponentCert() namespace = %v, want %v", cert.Namespace, namespace)
	}

	if cert.Name != "db-tidb-cluster-secret" {
		t.Errorf("TiDBComponentCert() name = %v, want %v", cert.Name, "db-tidb-cluster-secret")
	}

	if cert.Spec.SecretName != "db-tidb-cluster-secret" {
		t.Errorf("TiDBComponentCert() SecretName = %v, want %v", cert.Spec.SecretName, "db-tidb-cluster-secret")
	}
}

func TestComponentCert(t *testing.T) {
	tests := []struct {
		name      string
		compType  string
		compId    string
		namespace string
	}{
		{
			name:      "pd component with id",
			compType:  "pd",
			compId:    "test123",
			namespace: "default",
		},
		{
			name:      "tidb component with id",
			compType:  "tidb",
			compId:    "cluster1",
			namespace: "production",
		},
		{
			name:      "tikv component empty id",
			compType:  "tikv",
			compId:    "",
			namespace: "staging",
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			cert := ComponentCert(tt.compType, tt.compId, tt.namespace)

			if cert == nil {
				t.Fatal("ComponentCert() returned nil")
			}

			if cert.Namespace != tt.namespace {
				t.Errorf("ComponentCert() namespace = %v, want %v", cert.Namespace, tt.namespace)
			}

			expectedSecretName := certSecret(tt.compType, tt.compId)
			if cert.Spec.SecretName != expectedSecretName {
				t.Errorf("ComponentCert() SecretName = %v, want %v", cert.Spec.SecretName, expectedSecretName)
			}

			if cert.Name != expectedSecretName {
				t.Errorf("ComponentCert() name = %v, want %v", cert.Name, expectedSecretName)
			}

			// Verify certificate spec
			if cert.Spec.IssuerRef.Name != tidbComponentsSelfSignedIssuerName {
				t.Errorf("ComponentCert() IssuerRef.Name = %v, want %v", cert.Spec.IssuerRef.Name, tidbComponentsSelfSignedIssuerName)
			}
		})
	}
}

func TestTiDBServerCerts(t *testing.T) {
	namespace := "test-namespace"
	cert := TiDBServerCerts(namespace)

	if cert == nil {
		t.Fatal("TiDBServerCerts() returned nil")
	}

	if cert.Namespace != namespace {
		t.Errorf("TiDBServerCerts() namespace = %v, want %v", cert.Namespace, namespace)
	}

	expectedSecretName := ServerCertSecret("tidb", "")
	if cert.Spec.SecretName != expectedSecretName {
		t.Errorf("TiDBServerCerts() SecretName = %v, want %v", cert.Spec.SecretName, expectedSecretName)
	}

	if cert.Name != expectedSecretName {
		t.Errorf("TiDBServerCerts() name = %v, want %v", cert.Name, expectedSecretName)
	}

	// Check DNS names
	expectedDNSNames := getTiDBClusterServerDNSWildcard(namespace)
	if len(cert.Spec.DNSNames) != len(expectedDNSNames) {
		t.Errorf("TiDBServerCerts() DNS names count = %d, want %d", len(cert.Spec.DNSNames), len(expectedDNSNames))
	}

	if cert.Spec.Duration.Duration != tidbServerCertificateDuration {
		t.Errorf("TiDBServerCerts() duration = %v, want %v", cert.Spec.Duration.Duration, tidbServerCertificateDuration)
	}

	if cert.Spec.RenewBefore.Duration != renewBefore {
		t.Errorf("TiDBServerCerts() renewBefore = %v, want %v", cert.Spec.RenewBefore.Duration, renewBefore)
	}
}

func TestTiDBServerCertsWithDurationConfig(t *testing.T) {
	cert := TiDBServerCerts("test-namespace", WithDurationConfig(DurationConfig{
		TiDBServerDuration: 144 * time.Hour,
		RenewBefore:        24 * time.Hour,
	}))

	if cert.Spec.Duration.Duration != 144*time.Hour {
		t.Errorf("TiDBServerCerts() duration = %v, want %v", cert.Spec.Duration.Duration, 144*time.Hour)
	}

	if cert.Spec.RenewBefore.Duration != 24*time.Hour {
		t.Errorf("TiDBServerCerts() renewBefore = %v, want %v", cert.Spec.RenewBefore.Duration, 24*time.Hour)
	}
}

func TestTiProxyServerCerts(t *testing.T) {
	tests := []struct {
		name            string
		compId          string
		namespace       string
		gatewayIdentity string
		domainSuffix    string
		enablePCA       bool
	}{
		{
			name:            "with PCA enabled",
			compId:          "test123",
			namespace:       "default",
			gatewayIdentity: "identity1",
			domainSuffix:    "example.com",
			enablePCA:       true,
		},
		{
			name:            "without PCA",
			compId:          "cluster1",
			namespace:       "production",
			gatewayIdentity: "",
			domainSuffix:    "",
			enablePCA:       false,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			cert := TiProxyServerCerts(tt.compId, tt.namespace, tt.gatewayIdentity, tt.domainSuffix, tt.enablePCA)

			if cert == nil {
				t.Fatal("TiProxyServerCerts() returned nil")
			}

			if cert.Namespace != tt.namespace {
				t.Errorf("TiProxyServerCerts() namespace = %v, want %v", cert.Namespace, tt.namespace)
			}

			expectedSecretName := ServerCertSecret("tiproxy", tt.compId)
			if cert.Spec.SecretName != expectedSecretName {
				t.Errorf("TiProxyServerCerts() SecretName = %v, want %v", cert.Spec.SecretName, expectedSecretName)
			}

			// Check issuer ref based on PCA setting
			if tt.enablePCA {
				if cert.Spec.IssuerRef.Name != PCAIssuerName {
					t.Errorf("TiProxyServerCerts() with PCA IssuerRef.Name = %v, want %v", cert.Spec.IssuerRef.Name, PCAIssuerName)
				}
			} else {
				if cert.Spec.IssuerRef.Name != tidbComponentsSelfSignedIssuerName {
					t.Errorf("TiProxyServerCerts() without PCA IssuerRef.Name = %v, want %v", cert.Spec.IssuerRef.Name, tidbComponentsSelfSignedIssuerName)
				}
			}

			if cert.Spec.Duration.Duration != tiProxyServerCertificateDuration {
				t.Errorf("TiProxyServerCerts() duration = %v, want %v", cert.Spec.Duration.Duration, tiProxyServerCertificateDuration)
			}

			if cert.Spec.RenewBefore.Duration != renewBefore {
				t.Errorf("TiProxyServerCerts() renewBefore = %v, want %v", cert.Spec.RenewBefore.Duration, renewBefore)
			}
		})
	}
}

func TestTiProxyServerCertsWithDurationConfig(t *testing.T) {
	cert := TiProxyServerCerts("test123", "default", "identity1", "example.com", true, WithDurationConfig(DurationConfig{
		TiProxyServerDuration: 120 * time.Hour,
		RenewBefore:           24 * time.Hour,
	}))

	if cert.Spec.Duration.Duration != 120*time.Hour {
		t.Errorf("TiProxyServerCerts() duration = %v, want %v", cert.Spec.Duration.Duration, 120*time.Hour)
	}

	if cert.Spec.RenewBefore.Duration != 24*time.Hour {
		t.Errorf("TiProxyServerCerts() renewBefore = %v, want %v", cert.Spec.RenewBefore.Duration, 24*time.Hour)
	}

	if cert.Spec.IssuerRef.Name != PCAIssuerName {
		t.Errorf("TiProxyServerCerts() IssuerRef.Name = %v, want %v", cert.Spec.IssuerRef.Name, PCAIssuerName)
	}
}

func TestTiDBPrivilegedServerCert(t *testing.T) {
	tests := []struct {
		name      string
		compId    string
		namespace string
	}{
		{
			name:      "with component id",
			compId:    "test123",
			namespace: "default",
		},
		{
			name:      "empty component id",
			compId:    "",
			namespace: "production",
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			cert := TiDBPrivilegedServerCert(tt.compId, tt.namespace)

			if cert == nil {
				t.Fatal("TiDBPrivilegedServerCert() returned nil")
			}

			if cert.Namespace != tt.namespace {
				t.Errorf("TiDBPrivilegedServerCert() namespace = %v, want %v", cert.Namespace, tt.namespace)
			}

			expectedSecretName := ServerCertSecret(entity.TiDBPrivilegedType, tt.compId)
			if cert.Spec.SecretName != expectedSecretName {
				t.Errorf("TiDBPrivilegedServerCert() SecretName = %v, want %v", cert.Spec.SecretName, expectedSecretName)
			}

			if cert.Name != expectedSecretName {
				t.Errorf("TiDBPrivilegedServerCert() name = %v, want %v", cert.Name, expectedSecretName)
			}

			// Check DNS names contain expected privileged service names
			found := false
			expectedDNS := "db-" + tt.compId + "-privileged-tidb." + tt.namespace
			if tt.compId == "" {
				expectedDNS = "db--privileged-tidb." + tt.namespace
			}
			for _, dns := range cert.Spec.DNSNames {
				if dns == expectedDNS {
					found = true
					break
				}
			}
			if !found {
				t.Errorf("TiDBPrivilegedServerCert() missing expected DNS name: %s", expectedDNS)
			}
		})
	}
}

func TestClusterClientCert(t *testing.T) {
	namespace := "test-namespace"
	cert := ClusterClientCert(namespace)

	if cert == nil {
		t.Fatal("ClusterClientCert() returned nil")
	}

	if cert.Namespace != namespace {
		t.Errorf("ClusterClientCert() namespace = %v, want %v", cert.Namespace, namespace)
	}

	expectedSecretName := clientCertSecret()
	if cert.Spec.SecretName != expectedSecretName {
		t.Errorf("ClusterClientCert() SecretName = %v, want %v", cert.Spec.SecretName, expectedSecretName)
	}

	if cert.Name != expectedSecretName {
		t.Errorf("ClusterClientCert() name = %v, want %v", cert.Name, expectedSecretName)
	}

	// Check that it's configured for client auth
	foundClientAuth := false
	for _, usage := range cert.Spec.Usages {
		if usage == v1.UsageClientAuth {
			foundClientAuth = true
			break
		}
	}
	if !foundClientAuth {
		t.Error("ClusterClientCert() missing client auth usage")
	}
}

func TestTiBRCert(t *testing.T) {
	tests := []struct {
		name      string
		tibrName  string
		namespace string
	}{
		{
			name:      "simple name",
			tibrName:  "backup1",
			namespace: "default",
		},
		{
			name:      "complex name",
			tibrName:  "prod-backup-2024",
			namespace: "production",
		},
		{
			name:      "empty name",
			tibrName:  "",
			namespace: "test",
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			cert := TiBRCert(tt.tibrName, tt.namespace)

			if cert == nil {
				t.Fatal("TiBRCert() returned nil")
			}

			if cert.Namespace != tt.namespace {
				t.Errorf("TiBRCert() namespace = %v, want %v", cert.Namespace, tt.namespace)
			}

			expectedSecretName := TiBRCertName(tt.tibrName)
			if cert.Spec.SecretName != expectedSecretName {
				t.Errorf("TiBRCert() SecretName = %v, want %v", cert.Spec.SecretName, expectedSecretName)
			}

			if cert.Name != expectedSecretName {
				t.Errorf("TiBRCert() name = %v, want %v", cert.Name, expectedSecretName)
			}

			// Check DNS names
			expectedDNSNames := tibrDNSNames(tt.tibrName, tt.namespace)
			if len(cert.Spec.DNSNames) != len(expectedDNSNames) {
				t.Errorf("TiBRCert() DNS names count = %d, want %d", len(cert.Spec.DNSNames), len(expectedDNSNames))
			}

			for i, expectedDNS := range expectedDNSNames {
				if cert.Spec.DNSNames[i] != expectedDNS {
					t.Errorf("TiBRCert() DNSNames[%d] = %v, want %v", i, cert.Spec.DNSNames[i], expectedDNS)
				}
			}
		})
	}
}

// Tests for issuer.go functions
func TestClusterAgentServerCert(t *testing.T) {
	tests := []struct {
		name      string
		namespace string
	}{
		{
			name:      "standard namespace",
			namespace: "tidb12345",
		},
		{
			name:      "production namespace",
			namespace: "tidb-production",
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			c := ClusterAgentServerCert(tt.namespace)

			if c == nil {
				t.Fatal("ClusterAgentServerCert() returned nil")
			}

			if c.Name != clusterAgentServerCertSecret() {
				t.Errorf("Name = %v, want %v", c.Name, clusterAgentServerCertSecret())
			}
			if c.Namespace != tt.namespace {
				t.Errorf("Namespace = %v, want %v", c.Namespace, tt.namespace)
			}
			if c.Spec.SecretName != clusterAgentServerCertSecret() {
				t.Errorf("SecretName = %v, want %v", c.Spec.SecretName, clusterAgentServerCertSecret())
			}

			// Verify DNS names
			expectedDNS := clusterAgentDNSNames(tt.namespace)
			if len(c.Spec.DNSNames) != len(expectedDNS) {
				t.Errorf("DNSNames count = %d, want %d", len(c.Spec.DNSNames), len(expectedDNS))
			}
			for _, expected := range expectedDNS {
				found := false
				for _, actual := range c.Spec.DNSNames {
					if actual == expected {
						found = true
						break
					}
				}
				if !found {
					t.Errorf("missing expected DNS name: %s", expected)
				}
			}

			// Verify ServerAuth only
			wantUsages := []v1.KeyUsage{v1.UsageServerAuth}
			if len(c.Spec.Usages) != len(wantUsages) {
				t.Errorf("Usages count = %d, want %d", len(c.Spec.Usages), len(wantUsages))
			} else if c.Spec.Usages[0] != v1.UsageServerAuth {
				t.Errorf("Usages[0] = %v, want %v", c.Spec.Usages[0], v1.UsageServerAuth)
			}

			// Verify IssuerRef
			if c.Spec.IssuerRef.Name != tidbComponentsSelfSignedIssuerName {
				t.Errorf("IssuerRef.Name = %v, want %v", c.Spec.IssuerRef.Name, tidbComponentsSelfSignedIssuerName)
			}

			// Verify RotationPolicy
			if c.Spec.PrivateKey == nil || c.Spec.PrivateKey.RotationPolicy != v1.RotationPolicyAlways {
				t.Error("PrivateKey.RotationPolicy should be Always")
			}
		})
	}
}

// Tests for issuer.go functions
func TestSelfSignedComponentCACertificate(t *testing.T) {
	namespace := "test-namespace"
	cert := SelfSignedComponentCACertificate(namespace)

	if cert == nil {
		t.Fatal("SelfSignedComponentCACertificate() returned nil")
	}

	if cert.Namespace != namespace {
		t.Errorf("SelfSignedComponentCACertificate() namespace = %v, want %v", cert.Namespace, namespace)
	}

	if cert.Name != tidbComponentsSelfSignedCACertName {
		t.Errorf("SelfSignedComponentCACertificate() name = %v, want %v", cert.Name, tidbComponentsSelfSignedCACertName)
	}

	if cert.Spec.SecretName != tidbComponentSelfSignedCACertSecretName {
		t.Errorf("SelfSignedComponentCACertificate() SecretName = %v, want %v", cert.Spec.SecretName, tidbComponentSelfSignedCACertSecretName)
	}

	if !cert.Spec.IsCA {
		t.Error("SelfSignedComponentCACertificate() should be a CA certificate")
	}

	if cert.Spec.CommonName != "TiDB Components Self Signed CA" {
		t.Errorf("SelfSignedComponentCACertificate() CommonName = %v, want %v", cert.Spec.CommonName, "TiDB Components Self Signed CA")
	}
}

func TestTiDBComponentsSelfSignedIssuer(t *testing.T) {
	namespace := "test-namespace"
	issuer := TiDBComponentsSelfSignedIssuer(namespace)

	if issuer == nil {
		t.Fatal("TiDBComponentsSelfSignedIssuer() returned nil")
	}

	if issuer.Namespace != namespace {
		t.Errorf("TiDBComponentsSelfSignedIssuer() namespace = %v, want %v", issuer.Namespace, namespace)
	}

	if issuer.Name != tidbComponentsSelfSignedIssuerName {
		t.Errorf("TiDBComponentsSelfSignedIssuer() name = %v, want %v", issuer.Name, tidbComponentsSelfSignedIssuerName)
	}

	if issuer.Spec.CA == nil {
		t.Fatal("TiDBComponentsSelfSignedIssuer() CA config is nil")
	}

	if issuer.Spec.CA.SecretName != tidbComponentSelfSignedCACertSecretName {
		t.Errorf("TiDBComponentsSelfSignedIssuer() CA SecretName = %v, want %v", issuer.Spec.CA.SecretName, tidbComponentSelfSignedCACertSecretName)
	}
}
