package resourcepool

import (
	"testing"

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

	globalcommonv1 "github.com/tidbcloud/tidb-management-service/api/spec/global/common/v1"
	globalngv1 "github.com/tidbcloud/tidb-management-service/api/spec/global/nextgen/v1"
	"github.com/tidbcloud/tidb-management-service/utilities/bizerr"
)

func TestValidateCreateResourcePoolRequest_SharedPlanConstraint(t *testing.T) {
	tests := []struct {
		name    string
		request *globalngv1.CreateResourcePoolRequest
		wantErr bool
	}{
		{
			name: "shared with premium rejected",
			request: &globalngv1.CreateResourcePoolRequest{
				ResourcePool: &globalngv1.ResourcePool{
					OwnerType:   globalngv1.ResourcePool_SHARED,
					OwnerId:     0,
					ServicePlan: globalcommonv1.ServicePlan_Premium,
				},
			},
			wantErr: true,
		},
		{
			name: "shared with essential v2 accepted",
			request: &globalngv1.CreateResourcePoolRequest{
				ResourcePool: &globalngv1.ResourcePool{
					OwnerType:   globalngv1.ResourcePool_SHARED,
					OwnerId:     0,
					ServicePlan: globalcommonv1.ServicePlan_Essential_V2,
				},
			},
			wantErr: false,
		},

		{
			name: "placement group enabled with shared AWS accepted",
			request: &globalngv1.CreateResourcePoolRequest{
				ResourcePool: &globalngv1.ResourcePool{
					OwnerType:             globalngv1.ResourcePool_SHARED,
					OwnerId:               0,
					ServicePlan:           globalcommonv1.ServicePlan_Essential_V2,
					ProviderId:            globalcommonv1.CloudProvider_AWS,
					PlacementGroupEnabled: true,
				},
			},
			wantErr: false,
		},
		{
			name: "placement group enabled with alicloud rejected",
			request: &globalngv1.CreateResourcePoolRequest{
				ResourcePool: &globalngv1.ResourcePool{
					OwnerType:             globalngv1.ResourcePool_SHARED,
					OwnerId:               0,
					ServicePlan:           globalcommonv1.ServicePlan_Essential_V2,
					ProviderId:            globalcommonv1.CloudProvider_ALICLOUD,
					PlacementGroupEnabled: true,
				},
			},
			wantErr: true,
		},
		{
			name: "placement group enabled with organization premium AWS accepted",
			request: &globalngv1.CreateResourcePoolRequest{
				ResourcePool: &globalngv1.ResourcePool{
					OwnerType:             globalngv1.ResourcePool_ORGANIZATION,
					OwnerId:               123,
					ServicePlan:           globalcommonv1.ServicePlan_Premium,
					ProviderId:            globalcommonv1.CloudProvider_AWS,
					PlacementGroupEnabled: true,
				},
			},
			wantErr: false,
		},
		{
			name: "placement group enabled with organization BYOC AWS accepted",
			request: &globalngv1.CreateResourcePoolRequest{
				ResourcePool: &globalngv1.ResourcePool{
					OwnerType:             globalngv1.ResourcePool_ORGANIZATION,
					OwnerId:               123,
					ServicePlan:           globalcommonv1.ServicePlan_BYOC,
					ProviderId:            globalcommonv1.CloudProvider_AWS,
					PlacementGroupEnabled: true,
				},
			},
			wantErr: false,
		},
		{
			name: "placement group enabled with organization non-AWS rejected",
			request: &globalngv1.CreateResourcePoolRequest{
				ResourcePool: &globalngv1.ResourcePool{
					OwnerType:             globalngv1.ResourcePool_ORGANIZATION,
					OwnerId:               123,
					ServicePlan:           globalcommonv1.ServicePlan_BYOC,
					ProviderId:            globalcommonv1.CloudProvider_ALICLOUD,
					PlacementGroupEnabled: true,
				},
			},
			wantErr: true,
		},
		{
			name: "organization with premium accepted",
			request: &globalngv1.CreateResourcePoolRequest{
				ResourcePool: &globalngv1.ResourcePool{
					OwnerType:   globalngv1.ResourcePool_ORGANIZATION,
					OwnerId:     123,
					ServicePlan: globalcommonv1.ServicePlan_Premium,
				},
			},
			wantErr: false,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			err := validateCreateResourcePoolRequest(tt.request)
			if tt.wantErr {
				require.NotNil(t, err)
				assert.Equal(t, bizerr.ErrCodeParams, err.ErrCode())
				return
			}
			assert.Nil(t, err)
		})
	}
}
