package cluster

import (
	"context"
	"testing"

	. "github.com/onsi/gomega"
	observabilitypingcapcomv1 "github.com/tidbcloud/observability/api/regionalserver/resourceworker/v1"
	"github.com/tidbcloud/observability/pkg/common/constants"
	corev1 "k8s.io/api/core/v1"
	k8snetworkv1 "k8s.io/api/networking/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/runtime"
	utilruntime "k8s.io/apimachinery/pkg/util/runtime"
	"sigs.k8s.io/controller-runtime/pkg/client/fake"
)

// TestMakeIngress tests the actual makeIngress function execution for code coverage
func TestMakeIngress(t *testing.T) {
	g := NewGomegaWithT(t)

	// Setup fake Kubernetes client with proper schemes
	scheme := runtime.NewScheme()
	utilruntime.Must(corev1.AddToScheme(scheme))
	utilruntime.Must(k8snetworkv1.AddToScheme(scheme))
	client := fake.NewClientBuilder().WithScheme(scheme).Build()

	cls := &Cluster{
		cli: client,
	}

	// Helper to create cluster with different configurations
	createCluster := func(modifications func(*observabilitypingcapcomv1.Cluster)) *observabilitypingcapcomv1.Cluster {
		cluster := &observabilitypingcapcomv1.Cluster{
			ObjectMeta: metav1.ObjectMeta{
				Name:      "test-cluster",
				Namespace: "test-namespace",
				Labels: map[string]string{
					constants.LabelBizType:   "tidbcloud",
					constants.LabelTenantID:  "tenant-123",
					constants.LabelProjectID: "0",
				},
				Annotations: map[string]string{
					constants.AnnotationShareMode: string(constants.SHARED),
				},
			},
			Spec: observabilitypingcapcomv1.ClusterSpec{
				Endpoint: observabilitypingcapcomv1.Endpoint{
					Name:   "test-endpoint",
					Shared: true,
				},
				VictoriaAccount: observabilitypingcapcomv1.VictoriaAccount{
					ProjectID:         0,
					SupportServerless: false,
				},
			},
		}
		modifications(cluster)
		return cluster
	}

	ctx := context.Background()

	// Test all major branches of makeIngress function
	testCases := []struct {
		name         string
		setupCluster func(*observabilitypingcapcomv1.Cluster)
		description  string
	}{
		{
			name: "shared_mode_all_allowed",
			setupCluster: func(c *observabilitypingcapcomv1.Cluster) {
				// Default: shared mode, non-serverless, all ingresses allowed
			},
			description: "Shared mode with all ingresses allowed",
		},
		{
			name: "shared_mode_serverless_support",
			setupCluster: func(c *observabilitypingcapcomv1.Cluster) {
				c.Spec.VictoriaAccount.SupportServerless = true
			},
			description: "Shared mode with serverless support enabled",
		},
		{
			name: "shared_mode_serverless_cluster",
			setupCluster: func(c *observabilitypingcapcomv1.Cluster) {
				c.Labels[constants.LabelProjectID] = "123"
				c.Spec.VictoriaAccount.ProjectID = 123
			},
			description: "Shared mode with serverless cluster (ProjectID > 0)",
		},
		{
			name: "shared_mode_serverless_with_support",
			setupCluster: func(c *observabilitypingcapcomv1.Cluster) {
				c.Labels[constants.LabelProjectID] = "123"
				c.Spec.VictoriaAccount.ProjectID = 123
				c.Spec.VictoriaAccount.SupportServerless = true
			},
			description: "Shared mode serverless cluster with serverless support",
		},
		{
			name: "non_shared_mode",
			setupCluster: func(c *observabilitypingcapcomv1.Cluster) {
				c.Spec.Endpoint.Shared = false
				delete(c.Annotations, constants.AnnotationShareMode) // Remove shared annotation
				c.Spec.Prometheus = observabilitypingcapcomv1.Prometheus{
					Name: "test-prometheus",
				}
			},
			description: "Non-shared mode with Prometheus ingresses",
		},
		{
			name: "shared_mode_mixed_conditions",
			setupCluster: func(c *observabilitypingcapcomv1.Cluster) {
				// Regular cluster with serverless support
				c.Labels[constants.LabelProjectID] = "0"
				c.Spec.VictoriaAccount.ProjectID = 0
				c.Spec.VictoriaAccount.SupportServerless = true
			},
			description: "Shared mode regular cluster with serverless support",
		},
		{
			name: "non_shared_mode_minimal",
			setupCluster: func(c *observabilitypingcapcomv1.Cluster) {
				c.Spec.Endpoint.Shared = false
				// Remove shared mode annotation to ensure non-shared path
				delete(c.Annotations, constants.AnnotationShareMode)
				// Minimal prometheus setup
				c.Spec.Prometheus = observabilitypingcapcomv1.Prometheus{
					Name: "minimal-prometheus",
				}
			},
			description: "Non-shared mode with minimal configuration",
		},
		{
			name: "edge_case_empty_endpoint_name",
			setupCluster: func(c *observabilitypingcapcomv1.Cluster) {
				c.Spec.Endpoint.Name = "" // Edge case: empty endpoint name
			},
			description: "Shared mode with empty endpoint name",
		},
		{
			name: "shared_mode_all_rejected",
			setupCluster: func(c *observabilitypingcapcomv1.Cluster) {
				// Create a serverless cluster where all ingresses would be rejected
				c.Labels[constants.LabelProjectID] = "999"
				c.Spec.VictoriaAccount.ProjectID = 999
				c.Spec.VictoriaAccount.SupportServerless = false
			},
			description: "Shared mode serverless cluster with all ingresses rejected",
		},
	}

	for _, tc := range testCases {
		t.Run(tc.name, func(t *testing.T) {
			cluster := createCluster(tc.setupCluster)

			err := cls.makeIngress(ctx, cluster)

			// All test cases should succeed (not return errors)
			// The focus is on exercising all code paths
			g.Expect(err).To(BeNil(), "makeIngress should not return error for case: %s", tc.description)
		})
	}
}
