package dataplane

import (
	"testing"
)

func TestNewRESTConfigForEKS(t *testing.T) {
	tests := []struct {
		name       string
		k8sName    string
		endpoint   string
		region     string
		roleARN    string
		externalId string
		ca         []byte
		expectErr  bool
	}{
		{
			name:       "basic EKS config",
			k8sName:    "test-cluster",
			endpoint:   "https://test-cluster.eks.amazonaws.com",
			region:     "us-west-2",
			roleARN:    "",
			externalId: "",
			ca:         nil,
			expectErr:  false,
		},
		{
			name:       "EKS config with role ARN",
			k8sName:    "prod-cluster",
			endpoint:   "https://prod-cluster.eks.amazonaws.com",
			region:     "us-east-1",
			roleARN:    "arn:aws:iam::123456789012:role/EKSClusterRole",
			externalId: "",
			ca:         nil,
			expectErr:  false,
		},
		{
			name:       "EKS config with external ID",
			k8sName:    "dev-cluster",
			endpoint:   "https://dev-cluster.eks.amazonaws.com",
			region:     "eu-west-1",
			roleARN:    "arn:aws:iam::123456789012:role/EKSClusterRole",
			externalId: "external-id-123",
			ca:         nil,
			expectErr:  false,
		},
		{
			name:       "EKS config with CA",
			k8sName:    "secure-cluster",
			endpoint:   "https://secure-cluster.eks.amazonaws.com",
			region:     "us-west-2",
			roleARN:    "",
			externalId: "",
			ca:         []byte("-----BEGIN CERTIFICATE-----\nMII...\n-----END CERTIFICATE-----"),
			expectErr:  false,
		},
		{
			name:       "empty endpoint",
			k8sName:    "test-cluster",
			endpoint:   "",
			region:     "us-west-2",
			roleARN:    "",
			externalId: "",
			ca:         nil,
			expectErr:  true,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			config, err := NewRESTConfigForEKS(tt.k8sName, tt.endpoint, tt.region, tt.roleARN, tt.externalId, tt.ca)

			if tt.expectErr {
				if err == nil {
					t.Error("NewRESTConfigForEKS() expected error but got none")
				}
				return
			}

			if err != nil {
				t.Errorf("NewRESTConfigForEKS() unexpected error: %v", err)
				return
			}

			if config == nil {
				t.Error("NewRESTConfigForEKS() returned nil config")
				return
			}

			// Verify basic config properties
			if config.Host != tt.endpoint {
				t.Errorf("NewRESTConfigForEKS() host = %v, want %v", config.Host, tt.endpoint)
			}

			// Verify that the config has the expected structure
			if config.ExecProvider == nil {
				t.Error("NewRESTConfigForEKS() should have ExecProvider configured")
			}
		})
	}
}

func TestNewRESTConfigForGKE(t *testing.T) {
	tests := []struct {
		name      string
		endpoint  string
		ca        []byte
		expectErr bool
	}{
		{
			name:      "test-gke-cluster",
			endpoint:  "https://test-gke-cluster.gke.googleapis.com",
			ca:        nil,
			expectErr: false,
		},
		{
			name:      "secure-gke-cluster",
			endpoint:  "https://secure-gke-cluster.gke.googleapis.com",
			ca:        []byte("-----BEGIN CERTIFICATE-----\nMII...\n-----END CERTIFICATE-----"),
			expectErr: false,
		},
		{
			name:      "test-cluster",
			endpoint:  "",
			ca:        nil,
			expectErr: true,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			config, err := NewRESTConfigForGKE(tt.name, tt.endpoint, tt.ca)

			if tt.expectErr {
				if err == nil {
					t.Error("NewRESTConfigForGKE() expected error but got none")
				}
				return
			}

			if err != nil {
				t.Errorf("NewRESTConfigForGKE() unexpected error: %v", err)
				return
			}

			if config == nil {
				t.Error("NewRESTConfigForGKE() returned nil config")
				return
			}

			// Verify basic config properties
			if config.Host != tt.endpoint {
				t.Errorf("NewRESTConfigForGKE() host = %v, want %v", config.Host, tt.endpoint)
			}

			// Verify that the config has the expected structure
			if config.ExecProvider == nil {
				t.Error("NewRESTConfigForGKE() should have ExecProvider configured")
			}
		})
	}
}

func TestNewRESTConfigForKubeConfig(t *testing.T) {
	tests := []struct {
		name       string
		kubeconfig []byte
		expectErr  bool
	}{
		{
			name: "valid kubeconfig",
			kubeconfig: []byte(`apiVersion: v1
kind: Config
clusters:
- name: test-cluster
  cluster:
    server: https://test-cluster:6443
contexts:
- name: test-context
  context:
    cluster: test-cluster
    user: test-user
current-context: test-context
users:
- name: test-user
  user:
    token: test-token`),
			expectErr: false,
		},
		{
			name:       "empty kubeconfig",
			kubeconfig: []byte{},
			expectErr:  true,
		},
		{
			name:       "invalid kubeconfig",
			kubeconfig: []byte("invalid yaml content"),
			expectErr:  true,
		},
		{
			name:       "nil kubeconfig",
			kubeconfig: nil,
			expectErr:  true,
		},
	}

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

			if tt.expectErr {
				if err == nil {
					t.Error("NewRESTConfigForKubeConfig() expected error but got none")
				}
				return
			}

			if err != nil {
				t.Errorf("NewRESTConfigForKubeConfig() unexpected error: %v", err)
				return
			}

			if config == nil {
				t.Error("NewRESTConfigForKubeConfig() returned nil config")
				return
			}

			// Verify that the config is properly initialized
			if config.Host == "" {
				t.Error("NewRESTConfigForKubeConfig() should have a host configured")
			}
		})
	}
}

func TestNewRESTConfigForEKSWithInvalidArgs(t *testing.T) {
	// Test with invalid arguments that should cause errors
	tests := []struct {
		name       string
		k8sName    string
		endpoint   string
		region     string
		roleARN    string
		externalId string
		ca         []byte
	}{
		{
			name:       "invalid endpoint URL",
			k8sName:    "test-cluster",
			endpoint:   "not-a-valid-url",
			region:     "us-west-2",
			roleARN:    "",
			externalId: "",
			ca:         nil,
		},
		{
			name:       "invalid role ARN",
			k8sName:    "test-cluster",
			endpoint:   "https://test-cluster.eks.amazonaws.com",
			region:     "us-west-2",
			roleARN:    "invalid-arn",
			externalId: "",
			ca:         nil,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			config, err := NewRESTConfigForEKS(tt.k8sName, tt.endpoint, tt.region, tt.roleARN, tt.externalId, tt.ca)

			// These should either return an error or handle the invalid input gracefully
			if err != nil && config != nil {
				t.Error("NewRESTConfigForEKS() should not return both error and config")
			}
		})
	}
}

func TestNewRESTConfigForGKEWithInvalidArgs(t *testing.T) {
	// Test with invalid arguments that should cause errors
	tests := []struct {
		// name     string
		name     string
		endpoint string
		ca       []byte
	}{
		{
			//name:     "invalid endpoint URL",
			name:     "test-cluster",
			endpoint: "not-a-valid-url",
			ca:       nil,
		},
		{
			//name:     "invalid CA certificate",
			name:     "test-cluster",
			endpoint: "https://test-cluster.gke.googleapis.com",
			ca:       []byte("invalid-certificate"),
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			config, err := NewRESTConfigForGKE(tt.name, tt.endpoint, tt.ca)

			// These should either return an error or handle the invalid input gracefully
			if err != nil && config != nil {
				t.Error("NewRESTConfigForGKE() should not return both error and config")
			}
		})
	}
}

func TestConfigProperties(t *testing.T) {
	// Test that the generated configs have the expected properties
	t.Run("EKS config properties", func(t *testing.T) {
		config, err := NewRESTConfigForEKS("test-cluster", "https://test-cluster.eks.amazonaws.com", "us-west-2", "", "", nil)
		if err != nil {
			t.Skipf("Skipping test due to error: %v", err)
		}

		// Verify config has required fields
		if config.Host == "" {
			t.Error("EKS config should have host configured")
		}

		if config.ExecProvider == nil {
			t.Error("EKS config should have ExecProvider configured")
		}

		if config.ExecProvider.Command != "aws-iam-authenticator" {
			t.Errorf("EKS config should use aws-iam-authenticator, got %s", config.ExecProvider.Command)
		}
	})

	t.Run("GKE config properties", func(t *testing.T) {
		config, err := NewRESTConfigForGKE("test-cluster", "https://test-cluster.gke.googleapis.com", nil)
		if err != nil {
			t.Skipf("Skipping test due to error: %v", err)
		}

		// Verify config has required fields
		if config.Host == "" {
			t.Error("GKE config should have host configured")
		}

		if config.ExecProvider == nil {
			t.Error("GKE config should have ExecProvider configured")
		}

		if config.ExecProvider.Command != "gke-gcloud-auth-plugin" {
			t.Errorf("GKE config should use gke-gcloud-auth-plugin, got %s", config.ExecProvider.Command)
		}
	})
}
