package cvt

import (
	"errors"
	"fmt"

	"gorm.io/gorm"

	globaldedicatedv1 "github.com/tidbcloud/tidb-management-service/api/spec/global/dedicated/v1"
	"github.com/tidbcloud/tidb-management-service/dedicated-global-service/domain/entity"
	"github.com/tidbcloud/tidb-management-service/dedicated-global-service/infra/repoimpl/schema"
	"github.com/tidbcloud/tidb-management-service/utilities/enum"
)

func InstanceTypeEnToModel(en *entity.InstanceMu, providerId uint64) (*schema.InstanceType, error) {
	if en == nil {
		return nil, errors.New("instance type is nil")
	}

	return &schema.InstanceType{
		Model: gorm.Model{
			ID: uint(en.Id),
		},
		InstanceType: en.InstanceType,
		ProviderId:   providerId,
		CPUNum:       uint32(en.CpuCore),
		MemorySizeGi: uint32(en.MemoryGi),
		CpuArch:      en.CpuArch.String(),
	}, nil
}

func InstanceTypeModelToEn(m *schema.InstanceType, provider *schema.Provider) (*entity.InstanceMu, error) {
	if m == nil {
		return nil, errors.New("instance type is nil")
	}

	providerName, err := providerModel2En(provider.Name)
	if err != nil {
		return nil, err
	}
	arch, err := enum.FromString[globaldedicatedv1.InstanceMu_CpuArch](m.CpuArch)
	if err != nil {
		return nil, fmt.Errorf("invalid cpu arch: %s", m.CpuArch)
	}

	return &entity.InstanceMu{
		Id:            uint64(m.ID),
		InstanceType:  m.InstanceType,
		CloudProvider: providerName,
		CpuCore:       int32(m.CPUNum),
		MemoryGi:      int32(m.MemorySizeGi),
		CpuArch:       globaldedicatedv1.InstanceMu_CpuArch(arch),
	}, nil
}

func StorageTemplateEnToModel(en *entity.StorageMu, providerId uint64) (*schema.StorageTemplate, error) {
	if en == nil {
		return nil, errors.New("storage template is nil")
	}

	return &schema.StorageTemplate{
		Model: gorm.Model{
			ID: uint(en.Id),
		},
		VolumeType: en.VolumeType.String(),
		ProviderId: providerId,
	}, nil
}

func StorageTemplateModelToEn(m *schema.StorageTemplate, provider *schema.Provider) (*entity.StorageMu, error) {
	if m == nil {
		return nil, errors.New("storage template is nil")
	}

	providerName, err := providerModel2En(provider.Name)
	if err != nil {
		return nil, err
	}

	vt, err := enum.FromString[globaldedicatedv1.StorageMu_VolumeType](m.VolumeType)
	if err != nil {
		return nil, fmt.Errorf("invalid cpu arch: %s", m.VolumeType)
	}

	return &entity.StorageMu{
		Id:            uint64(m.ID),
		VolumeType:    globaldedicatedv1.StorageMu_VolumeType(vt),
		CloudProvider: providerName,
	}, nil
}
