package config

import (
	"testing"

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

func TestPrecheckSkipConfigs_GetSkippedItems(t *testing.T) {
	tests := map[string]struct {
		configs   PrecheckSkipConfigs
		tenantID  uint64
		projectID uint64
		clusterID uint64
		expected  map[string]bool
	}{
		"empty configs returns empty map": {
			configs:   PrecheckSkipConfigs{},
			tenantID:  1,
			projectID: 2,
			clusterID: 3,
			expected:  map[string]bool{},
		},
		"match by tenantID": {
			configs: PrecheckSkipConfigs{
				{
					Matcher:   AllowListMatcher{TenantID: []string{"10"}},
					SkipItems: []string{"version_checking", "dump_privilege_checking"},
				},
			},
			tenantID:  10,
			projectID: 0,
			clusterID: 0,
			expected:  map[string]bool{"version_checking": true, "dump_privilege_checking": true},
		},
		"match by projectID": {
			configs: PrecheckSkipConfigs{
				{
					Matcher:   AllowListMatcher{ProjectID: []string{"20"}},
					SkipItems: []string{"server_id_checking"},
				},
			},
			tenantID:  0,
			projectID: 20,
			clusterID: 0,
			expected:  map[string]bool{"server_id_checking": true},
		},
		"match by clusterID": {
			configs: PrecheckSkipConfigs{
				{
					Matcher:   AllowListMatcher{ClusterID: []string{"30"}},
					SkipItems: []string{"binlog_enable_checking"},
				},
			},
			tenantID:  0,
			projectID: 0,
			clusterID: 30,
			expected:  map[string]bool{"binlog_enable_checking": true},
		},
		"no match returns empty map": {
			configs: PrecheckSkipConfigs{
				{
					Matcher:   AllowListMatcher{TenantID: []string{"99"}},
					SkipItems: []string{"version_checking"},
				},
			},
			tenantID:  1,
			projectID: 2,
			clusterID: 3,
			expected:  map[string]bool{},
		},
		"first matching entry wins": {
			configs: PrecheckSkipConfigs{
				{
					Matcher:   AllowListMatcher{TenantID: []string{"10"}},
					SkipItems: []string{"version_checking"},
				},
				{
					Matcher:   AllowListMatcher{TenantID: []string{"10"}},
					SkipItems: []string{"binlog_enable_checking"},
				},
			},
			tenantID:  10,
			projectID: 0,
			clusterID: 0,
			expected:  map[string]bool{"version_checking": true},
		},
	}

	for name, tc := range tests {
		t.Run(name, func(t *testing.T) {
			got := tc.configs.GetSkippedItems(tc.tenantID, tc.projectID, tc.clusterID)
			require.Equal(t, tc.expected, got)
		})
	}
}

func TestPrecheckSkipConfigs_ApplyBlacklist(t *testing.T) {
	tests := map[string]struct {
		configs   PrecheckSkipConfigs
		items     []string
		tenantID  uint64
		projectID uint64
		clusterID uint64
		expected  []string
	}{
		"empty configs returns all items": {
			configs:   PrecheckSkipConfigs{},
			items:     []string{"a", "b", "c"},
			tenantID:  1,
			projectID: 2,
			clusterID: 3,
			expected:  []string{"a", "b", "c"},
		},
		"removes matched skip items": {
			configs: PrecheckSkipConfigs{
				{
					Matcher:   AllowListMatcher{ClusterID: []string{"30"}},
					SkipItems: []string{"b"},
				},
			},
			items:     []string{"a", "b", "c"},
			tenantID:  0,
			projectID: 0,
			clusterID: 30,
			expected:  []string{"a", "c"},
		},
	}

	for name, tc := range tests {
		t.Run(name, func(t *testing.T) {
			got := tc.configs.ApplyBlacklist(tc.items, tc.tenantID, tc.projectID, tc.clusterID)
			require.Equal(t, tc.expected, got)
		})
	}
}
