package cluster

import (
	"testing"

	"github.com/stretchr/testify/require"

	"github.com/pingcap-inc/clinic/pkg/auth/session"
	"github.com/pingcap-inc/clinic/pkg/datasource/view"
	"github.com/pingcap-inc/clinic/pkg/db"
	"github.com/pingcap-inc/clinic/pkg/o11y"
)

func TestRedactExternalDedicatedResourcePoolComponents(t *testing.T) {
	storage := &view.ResourcePoolStorage{
		Name:          "data",
		Type:          "gp3",
		SizeGi:        500,
		Iops:          3000,
		ThroughputMbs: 125,
	}
	components := []*view.ResourcePoolComponent{
		{Id: "pd-short", ComponentType: "PD", Storages: []*view.ResourcePoolStorage{storage}},
		{Id: "pd-prefixed", ComponentType: "COMPONENT_TYPE_PD", Storages: []*view.ResourcePoolStorage{storage}},
		{Id: "tidb", ComponentType: "TIDB", Storages: []*view.ResourcePoolStorage{storage}},
		{Id: "tikv", ComponentType: "COMPONENT_TYPE_TIKV", Storages: []*view.ResourcePoolStorage{storage}},
	}
	externalUser := &session.CtxUser{Internal: false}
	dedicatedCluster := &db.Cluster{DeployTypeV2: o11y.DeployTypeV2Dedicated}

	got, redacted := redactExternalDedicatedResourcePoolComponents(externalUser, dedicatedCluster, components)

	require.True(t, redacted)
	require.Len(t, got, 2)
	require.Equal(t, "tidb", got[0].Id)
	require.Equal(t, "tikv", got[1].Id)
	require.Empty(t, got[0].Storages)
	require.Empty(t, got[1].Storages)
	require.NotSame(t, components[2], got[0])
	require.NotSame(t, components[3], got[1])
	require.Equal(t, []*view.ResourcePoolStorage{storage}, components[2].Storages)
	require.Equal(t, []*view.ResourcePoolStorage{storage}, components[3].Storages)
}

func TestRedactExternalDedicatedResourcePoolComponentsPreservesOtherViews(t *testing.T) {
	components := []*view.ResourcePoolComponent{{
		Id:            "pd",
		ComponentType: "PD",
		Storages:      []*view.ResourcePoolStorage{{Name: "data", Type: "gp3"}},
	}}

	tests := []struct {
		name    string
		user    *session.CtxUser
		cluster *db.Cluster
	}{
		{
			name:    "internal dedicated",
			user:    &session.CtxUser{Internal: true},
			cluster: &db.Cluster{DeployTypeV2: o11y.DeployTypeV2Dedicated},
		},
		{
			name:    "external non-dedicated",
			user:    &session.CtxUser{Internal: false},
			cluster: &db.Cluster{DeployTypeV2: o11y.DeployTypeV2Premium},
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			got, redacted := redactExternalDedicatedResourcePoolComponents(tt.user, tt.cluster, components)

			require.False(t, redacted)
			require.Len(t, got, 1)
			require.Same(t, components[0], got[0])
			require.Equal(t, components[0].Storages, got[0].Storages)
		})
	}
}
