package labels

import (
	"testing"

	"github.com/stretchr/testify/assert"
)

func TestNewKubeClusterLabels(t *testing.T) {
	cases := []struct {
		labels          map[string]string
		kubeClusterName string
		resultLabels    map[string]string
	}{
		{
			labels: map[string]string{
				"tags.tidbcloud.com/kubernetes": "testName",
			},
			kubeClusterName: "testName",
			resultLabels: map[string]string{
				"tags.tidbcloud.com/kubernetes": "testName",
			},
		},
		{
			labels:          nil,
			kubeClusterName: "NewFakeName",
			resultLabels: map[string]string{
				"tags.tidbcloud.com/kubernetes": "NewFakeName",
			},
		},
		{
			labels:          map[string]string{},
			kubeClusterName: "NewFakeName",
			resultLabels: map[string]string{
				"tags.tidbcloud.com/kubernetes": "NewFakeName",
			},
		},
		{
			labels: map[string]string{
				"tags.tidbcloud.com/kubernetes": "NewFakeName",
				"tags.tidbcloud.com/clusters":   "NewFakeName",
				"tags.tidbcloud.com/tiflash":    "tiflash",
				"tags.tidbcloud.com/tikv":       "tikv",
			},
			kubeClusterName: "NewFakeName",
			resultLabels: map[string]string{
				"tags.tidbcloud.com/kubernetes": "NewFakeName",
				"tags.tidbcloud.com/clusters":   "NewFakeName",
				"tags.tidbcloud.com/tiflash":    "tiflash",
				"tags.tidbcloud.com/tikv":       "tikv",
			},
		},
	}

	for _, c := range cases {
		newLabels := NewKubeClusterLabels(c.labels, c.kubeClusterName)

		for key, val := range newLabels {
			assert.Equal(t, val, c.resultLabels[key])
		}

		// deep compare
		delete(newLabels, "tags.tidbcloud.com/kubernetes")
		delete(c.labels, "tags.tidbcloud.com/kubernetes")
		assert.Equal(t, len(newLabels), len(c.labels))
		for key, val := range newLabels {
			assert.Equal(t, val, c.labels[key])
		}
	}
}

func TestTagsFromLabels(t *testing.T) {
	cases := []struct {
		labels         map[string]string
		resultLabels   map[string]string
		expectedFailed bool
		errors         int
	}{
		{
			labels: map[string]string{
				"tags.tidbcloud.com/kubernetes": "testName",
			},
			resultLabels: map[string]string{
				"tags.tidbcloud.com/kubernetes": "testName",
			},
			expectedFailed: false,
			errors:         0,
		},
		{
			labels:         nil,
			resultLabels:   map[string]string{},
			expectedFailed: false,
			errors:         0,
		},
		{
			labels: map[string]string{},
			resultLabels: map[string]string{
				"tags.tidbcloud.com/kubernetes": "NewFakeName",
			},
			expectedFailed: false,
			errors:         0,
		},
		{
			labels: map[string]string{
				"tags.tidbcloud.com/kubernetes": "NewFakeName",
				"tags.tidbcloud.com/clusters":   "NewFakeName",
				"tags.tidbcloud.com/tiflash":    "tiflash",
				"tags.tidbcloud.com/tikv":       "tikv",
			},
			resultLabels: map[string]string{
				"tags.tidbcloud.com/kubernetes": "NewFakeName",
				"tags.tidbcloud.com/clusters":   "NewFakeName",
				"tags.tidbcloud.com/tiflash":    "tiflash",
				"tags.tidbcloud.com/tikv":       "tikv",
			},
			expectedFailed: false,
			errors:         0,
		},
		{
			labels: map[string]string{
				"tags.tidbcloud.com/kubernetstestesttestest" +
					"testtesttesttesttesttesttesttesttest": "NewFakeName",
				"tags.tidbcloud.com/clusters": "NewFakeName",
				"tags.tidbcloud.com/tiflash":  "tiflash",
				"tags.tidbcloud.com/tikv":     "tikv",
			},
			resultLabels: map[string]string{
				"tags.tidbcloud.com/clusters": "NewFakeName",
				"tags.tidbcloud.com/tiflash":  "tiflash",
				"tags.tidbcloud.com/tikv":     "tikv",
			},
			expectedFailed: true,
			errors:         1,
		},
		{
			labels: map[string]string{
				"tags.tidbcloud.com/kubernetstestes.>,（）中国（": "NewFakeName111",
				"tags.tidbcloud.com/clusters":                "NewFakeName",
				"tags.tidbcloud.com/tiflash":                 "tiflash",
				"tags.tidbcloud.com/tikv":                    "tikv",
			},
			resultLabels: map[string]string{
				"tags.tidbcloud.com/clusters": "NewFakeName",
				"tags.tidbcloud.com/tiflash":  "tiflash",
				"tags.tidbcloud.com/tikv":     "tikv",
			},
			expectedFailed: true,
			errors:         1,
		},
		{
			labels: map[string]string{
				"tags.tidbcloud.com/kubernetstestes.>,*91*&&": "NewFakeName",
				"tags.tidbcloud.com/clusters":                 "NewFakeName",
				"tags.tidbcloud.com/tiflash":                  "tiflash",
				"tags.tidbcloud.com/tikv":                     "tikv",
			},
			resultLabels: map[string]string{
				"tags.tidbcloud.com/clusters": "NewFakeName",
				"tags.tidbcloud.com/tiflash":  "tiflash",
				"tags.tidbcloud.com/tikv":     "tikv",
			},
			expectedFailed: true,
			errors:         1,
		},
		{
			labels: map[string]string{
				"tags.tidbcloud.com/kubernetes": "NewFakeName^^^()",
				"tags.tidbcloud.com/clusters":   "NewFakeName",
				"tags.tidbcloud.com/tiflash":    "tiflash",
				"tags.tidbcloud.com/tikv":       "tikv",
			},
			resultLabels: map[string]string{
				"tags.tidbcloud.com/clusters": "NewFakeName",
				"tags.tidbcloud.com/tiflash":  "tiflash",
				"tags.tidbcloud.com/tikv":     "tikv",
			},
			expectedFailed: true,
			errors:         1,
		},
		{
			labels: map[string]string{
				"tags.tidbcloud.com/kubernetes": "NewFakeNameNewFake" +
					"NameNewFakeNameNewFakeNameNewFakeNameNewFakeNameNewFakeNameNekkkkk",
				"tags.tidbcloud.com/clusters": "NewFakeName",
				"tags.tidbcloud.com/tiflash":  "tiflash",
				"tags.tidbcloud.com/tikv":     "tikv",
			},
			resultLabels: map[string]string{
				"tags.tidbcloud.com/clusters": "NewFakeName",
				"tags.tidbcloud.com/tiflash":  "tiflash",
				"tags.tidbcloud.com/tikv":     "tikv",
			},
			expectedFailed: true,
			errors:         1,
		},
	}

	for _, c := range cases {
		newLabels, errLists := TagsFromLabels(c.labels)
		for key, val := range newLabels {
			assert.Equal(t, val, c.resultLabels[key])
		}
		assert.Equal(t, len(errLists), c.errors)

		if !c.expectedFailed {
			assert.Equal(t, len(newLabels), len(c.labels))
		} else {
			assert.Equal(t, len(newLabels), len(c.resultLabels))
		}

		// deep compare
		delete(newLabels, "tags.tidbcloud.com/kubernetes")
		delete(c.labels, "tags.tidbcloud.com/kubernetes")

		for key, val := range newLabels {
			assert.Equal(t, val, c.labels[key])
		}
	}
}
