package impl

import (
	"context"
	"testing"

	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/mock"
	"github.com/tidbcloud/dataflow-service/app/models/domain"
	ticdc_spec_mock "github.com/tidbcloud/dataflow-service/app/models/ticdc_spec/mock"
	"github.com/tidbcloud/dataflow-service/app/repo/entity"
)

func TestChangefeedInstanceType2Specification(t *testing.T) {
	mockChangefeedInstanceType := &entity.ChangefeedInstanceType{
		Name:     "16rcu",
		RCUNum:   16,
		RPSLimit: 160000,
	}
	expectedSpec := &domain.TiCDCClusterSpecification{
		Code:     "16rcu",
		RCUNum:   16,
		RPSLimit: 160000,
	}
	spec := changefeedInstanceType2Specification(mockChangefeedInstanceType)
	assert.Equal(t, expectedSpec, spec)
}

func TestMachineManagerChangefeedWrapperImpl_Query(t *testing.T) {
	mockInstanceTypeModel := ticdc_spec_mock.NewCDCInstanceTypeModel(t)
	machineManager := &machineManagerChangefeedWrapperImpl{instanceTypeModel: mockInstanceTypeModel}
	mockQueryReq := &domain.QuerySpecificationReq{
		Code: "16rcu",
	}
	expectedInstanceTypeReq := &domain.GetChangefeedInstanceTypeReq{
		Name: "16rcu",
	}
	mockInstanceType := &entity.ChangefeedInstanceType{
		Name:     "16rcu",
		RCUNum:   16,
		RPSLimit: 160000,
	}
	call := mockInstanceTypeModel.
		On("GetChangefeedInstanceType", mock.Anything, expectedInstanceTypeReq).
		Return(&domain.GetChangefeedInstanceTypeResp{InstanceType: mockInstanceType}, nil)
	defer call.Unset()
	resp, err := machineManager.Query(context.Background(), mockQueryReq)
	assert.NoError(t, err)
	assert.Equal(t, mockInstanceType.Name, resp.Specification.Code)
	assert.Equal(t, mockInstanceType.RCUNum, resp.Specification.GetRCUNumber())
	assert.Equal(t, mockInstanceType.RPSLimit, resp.Specification.RPSLimit)
}

func TestMachineManagerChangefeedWrapperImpl_ListSpecifications(t *testing.T) {
	mockInstanceTypeModel := ticdc_spec_mock.NewCDCInstanceTypeModel(t)
	machineManager := &machineManagerChangefeedWrapperImpl{instanceTypeModel: mockInstanceTypeModel}
	mockListReq := &domain.ListSpecificationsReq{}
	mockInstanceTypes := []*entity.ChangefeedInstanceType{
		{
			Name:     "8rcu",
			RCUNum:   8,
			RPSLimit: 80000,
		},
		{
			Name:     "16rcu",
			RCUNum:   16,
			RPSLimit: 160000,
		},
		{
			Name:     "24rcu",
			RCUNum:   24,
			RPSLimit: 240000,
		},
	}
	call := mockInstanceTypeModel.
		On("ListChangefeedInstanceTypes", mock.Anything).
		Return(&domain.ListChangefeedInstanceTypesResp{InstanceTypes: mockInstanceTypes}, nil)
	defer call.Unset()
	resp, err := machineManager.ListSpecifications(context.Background(), mockListReq)
	assert.NoError(t, err)
	assert.Equal(t, len(mockInstanceTypes), len(resp.Specifications))
	for i := range resp.Specifications {
		assert.Equal(t, mockInstanceTypes[i].Name, resp.Specifications[i].Code)
		assert.Equal(t, mockInstanceTypes[i].RCUNum, resp.Specifications[i].GetRCUNumber())
		assert.Equal(t, mockInstanceTypes[i].RPSLimit, resp.Specifications[i].RPSLimit)
	}
}
