package selfmanaged

import (
	"reflect"
	"testing"

	eksv1beta1 "github.com/crossplane-contrib/provider-aws/apis/eks/v1beta1"
	corev1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

	"github.com/tidbcloud/infra-provider/pkg/config"
)

func getTestRootConfig(featureGate config.FeatureGate, amiCfg *config.WorkerNodeAMIConfig, defaultVersion string) config.RootConfig {
	cfg := config.RootConfig{
		ControllerConfig: config.ControllerConfig{
			FeatureGates: map[config.FeatureGateName]config.FeatureGate{},
			Network: config.NetworkConfig{
				K8sVersion: defaultVersion,
			},
		},
	}
	if amiCfg != nil {
		cfg.ControllerConfig.AMIConfig = *amiCfg
	}
	return cfg
}

func TestOverwriteNodeLabels(t *testing.T) {
	eks := &eksv1beta1.Cluster{
		ObjectMeta: metav1.ObjectMeta{
			Name: "my-cluster",
		},
		Status: eksv1beta1.ClusterStatus{
			AtProvider: eksv1beta1.ClusterObservation{
				Arn:                      "arn:aws:eks:us-west-2:123456789012:cluster/my-cluster",
				Endpoint:                 "test",
				CertificateAuthorityData: "test",
			},
		},
	}
	taints := []corev1.Taint{
		{
			Key:    "test",
			Value:  "test",
			Effect: corev1.TaintEffectNoSchedule,
		},
	}

	systemConfiguration := `
[settings.oci-defaults.resource-limits.max-open-files]
"hard-limit" = 1048576
"soft-limit" = 1048576
`

	tests := []struct {
		name          string
		oldNodeLabels map[string]string
		newNodeLabels map[string]string
	}{
		{
			name: "overwrite node labels",
			oldNodeLabels: map[string]string{
				"foo": "bar",
			},
			newNodeLabels: map[string]string{
				"foo": "baz",
			},
		},
		{
			name: "append node labels",
			oldNodeLabels: map[string]string{
				"foo": "bar",
			},
			newNodeLabels: map[string]string{
				"foo": "bar",
				"bar": "baz",
			},
		},
		{
			name: "remove node labels",
			oldNodeLabels: map[string]string{
				"foo": "bar",
			},
			newNodeLabels: map[string]string{
				"bar": "baz",
			},
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			userData := GetBottlerocketUserData(eks.Name, eks.Status.AtProvider.Endpoint, eks.Status.AtProvider.CertificateAuthorityData, tt.oldNodeLabels, taints, systemConfiguration)
			want := GetBottlerocketUserData(eks.Name, eks.Status.AtProvider.Endpoint, eks.Status.AtProvider.CertificateAuthorityData, tt.newNodeLabels, taints, systemConfiguration)

			got := OverwriteNodeLabels(*userData, tt.newNodeLabels)
			if !reflect.DeepEqual(got, want) {
				t.Errorf("OverwriteNodeLabels() got = %v, want %v", got, want)
			}
		})
	}
}
