package client_test

import (
	"context"
	"encoding/json"
	"testing"
	"time"

	"github.com/stretchr/testify/assert"
	"go.uber.org/mock/gomock"
	decortsdk "repository.basistech.ru/BASIS/decort-golang-sdk"
	"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/compute"
	"repository.basistech.ru/BASIS/decort-golang-sdk/samples/client"
)

// Пример юнит тестирования на моках
func TestClient(t *testing.T) {
	ctrl := gomock.NewController(t)
	// Создаем мок инстанс интерфейса Caller
	mockCaller := decortsdk.NewMockCaller(ctrl)
	// Создаем мок инстанс интерфейса DecortClient
	mockClient := decortsdk.NewMockDecortClient(mockCaller)

	dxVMID := uint64(100500)
	VMID := "vm-100500"

	listComputes := &compute.ListComputes{
		Data: []compute.ItemCompute{
			{
				InfoCompute: compute.InfoCompute{
					ID:          dxVMID,
					ReferenceID: VMID,
				},
			},
		}}

	b, err := json.Marshal(listComputes)
	assert.NoError(t, err)
	// Подготавливаем мок для вызова метода CloudBroker().Compute().List()
	mockCaller.EXPECT().DecortApiCall(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Eq(compute.ListRequest{})).Return(b, nil).AnyTimes()
	listComputesRet, err := mockClient.CloudBroker().Compute().List(context.Background(), compute.ListRequest{})
	assert.NoError(t, err)

	assert.Equal(t, listComputes, listComputesRet)

}

// Пример юнит тестирования на моках
func TestMigrator(t *testing.T) {
	ctrl := gomock.NewController(t)
	// Создаем мок инстанс интерфейса Caller
	mockCaller := decortsdk.NewMockCaller(ctrl)
	// Создаем мок инстанс интерфейса interfaces.ClientInterface
	mockClient := decortsdk.NewMockDecortClient(mockCaller)

	// Передаем мок инстанс интерфейса interfaces.ClientInterface в конструктор Migrator
	migrator := client.NewMigrator(&client.Config{QueryTimeout: time.Second}, mockClient)

	b, err := json.Marshal(true)
	assert.NoError(t, err)

	dxVMID := uint64(100500)
	nodeID := uint64(100501)

	// Записываем поведение клиента
	mockCaller.EXPECT().DecortApiCall(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Eq(compute.AsyncWrapperMigrateRequest{
		MigrateRequest: compute.MigrateRequest{
			ComputeID:    dxVMID,
			TargetNodeID: nodeID,
		},
		SyncMode: true})).Return(b, nil).AnyTimes()

	ok, err := migrator.Migrate(context.Background(), dxVMID, nodeID)
	assert.NoError(t, err)
	assert.True(t, ok)
}
