package rcuquota

import (
	"context"
	"testing"

	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
	"go.uber.org/mock/gomock"

	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/nextgen-global-service/domain/entity"
	"github.com/tidbcloud/tidb-management-service/nextgen-global-service/domain/repository/cluster/mock_cluster"
	"github.com/tidbcloud/tidb-management-service/nextgen-global-service/domain/repository/rcuquota/mock_rcuquota"
	"github.com/tidbcloud/tidb-management-service/utilities/workflow/mock_workflow"
)

type mockTransactioner struct{}

func (m *mockTransactioner) Transaction(ctx context.Context, fn func(ctx context.Context) error) error {
	return fn(ctx)
}

func TestUpdateRcuQuota_Scenario(t *testing.T) {
	ctrl := gomock.NewController(t)
	defer ctrl.Finish()

	mockRepo := mock_rcuquota.NewMockRepo(ctrl)
	mockClusterRepo := mock_cluster.NewMockRepo(ctrl)
	mockWorkflow := mock_workflow.NewMockWorkflow(ctrl)

	svc := NewService(
		&mockTransactioner{},
		mockRepo,
		mockClusterRepo,
		mockWorkflow,
	)

	ctx := context.Background()
	orgID := uint64(123)
	plan := globalcommonv1.ServicePlan_Premium

	request := &globalngv1.UpdateRcuQuotaRequest{
		RcuQuota: &entity.RcuQuota{
			OrganizationId:     orgID,
			ServicePlan:        plan,
			MinimalRcuBaseline: 2000,
		},
	}

	existing := &entity.RcuQuota{
		OrganizationId:     orgID,
		ServicePlan:        plan,
		InstanceMaxRcu:     10000,
		TotalMaxRcu:        50000,
		BurstyRatio:        1.2,
		MinimalRcuBaseline: 1000,
	}
	mockRepo.EXPECT().Load(gomock.Any(), gomock.Any(), gomock.Any()).Return(existing, nil)

	mockRepo.EXPECT().Save(gomock.Any(), gomock.Any()).Return(nil)

	res, err := svc.UpdateRcuQuota(ctx, request)
	require.NoError(t, err)
	assert.Equal(t, uint64(2000), res.MinimalRcuBaseline)
	assert.InEpsilon(t, float32(1.2), res.BurstyRatio, 1e-6) // Preserved from existing
}
