/*

 Copyright (c) [2023] [pcm]
 [pcm-coordinator] is licensed under Mulan PSL v2.
 You can use this software according to the terms and conditions of the Mulan PSL v2.
 You may obtain a copy of Mulan PSL v2 at:
          http://license.coscl.org.cn/MulanPSL2
 THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 EITHER EXPaRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 See the Mulan PSL v2 for more details.

*/

package storeLink

import (
	"context"
	"fmt"
	"github.com/pkg/errors"
	"gitlink.org.cn/JointCloud/pcm-ac/hpcAC"
	hpcacclient "gitlink.org.cn/JointCloud/pcm-ac/hpcacclient"
	"gitlink.org.cn/JointCloud/pcm-coordinator/internal/scheduler/common"
	"gitlink.org.cn/JointCloud/pcm-coordinator/internal/scheduler/service/collector"
	"gitlink.org.cn/JointCloud/pcm-coordinator/internal/types"
	"gitlink.org.cn/JointCloud/pcm-coordinator/pkg/models"
	"gitlink.org.cn/JointCloud/pcm-coordinator/pkg/utils/timeutils"
	"gitlink.org.cn/JointCloud/pcm-modelarts/client/imagesservice"
	"gitlink.org.cn/JointCloud/pcm-modelarts/client/modelartsservice"
	"gitlink.org.cn/JointCloud/pcm-modelarts/modelarts"
	"gitlink.org.cn/JointCloud/pcm-octopus/octopus"
	"gitlink.org.cn/JointCloud/pcm-octopus/octopusclient"
	"gorm.io/gorm"
	"strings"
	"sync"
)

type Linkage interface {
	UploadImage(ctx context.Context, path string) (interface{}, error)
	DeleteImage(ctx context.Context, imageId string) (interface{}, error)
	QueryImageList(ctx context.Context) (interface{}, error)
	SubmitTask(ctx context.Context, imageId string, cmd string, envs []string, params []string, resourceId string, datasetsId string, algorithmId string, aiType string) (interface{}, error)
	QueryTask(ctx context.Context, taskId string) (interface{}, error)
	QuerySpecs(ctx context.Context) (interface{}, error)
	DeleteTask(ctx context.Context, taskId string) (interface{}, error)
}

const (
	COLON                   = ":"
	PY_PARAM_PREFIX         = "--"
	SPACE                   = " "
	UNDERSCORE              = "_"
	EQUAL                   = "="
	DASH                    = "-"
	FORWARD_SLASH           = "/"
	COMMA                   = ","
	STAR                    = "*"
	TYPE_OCTOPUS            = "1"
	TYPE_MODELARTS          = "2"
	TYPE_SHUGUANGAI         = "3"
	TYPE_SHUGUANGHPC        = "4"
	OCTOPUS                 = "Octopus"
	MODELARTS               = "Modelarts"
	SHUGUANGAI              = "ShuguangAi"
	SHUGUANGHPC             = "ShuguangHpc"
	CPU                     = "cpu"
	GPU                     = "gpu"
	NPU                     = "npu"
	CARD                    = "computeCard"
	PYTORCH_TASK            = "pytorch"
	TENSORFLOW_TASK         = "tensorflow"
	DEPLOY_INSTANCE_PREFIEX = "infer"
)

var (
	Datasets              = []string{"mnist", "cifar10"}
	AlgorithmsForDatasets = map[string][]string{
		"mnist":   {"fcn"},
		"cifar10": {"cnn"},
	}
	OctImgStatus = map[int32]string{
		1: "未上传",
		3: "制作完成",
		4: "制作失败",
	}
	ModelTypeMap = map[string][]string{
		"image_classification": {"imagenet_resnet50"},
		"text_to_text":         {"ChatGLM-6B"},
		"image_to_text":        {"blip-image-captioning-base"},
		"text_to_image":        {"stable-diffusion-xl-base-1.0"},
	}
	AITYPE = map[string]string{
		"1": OCTOPUS,
		"2": MODELARTS,
		"3": SHUGUANGAI,
		"4": SHUGUANGHPC,
	}
	resourceTypes = []string{CARD}
	taskTypes     = []string{PYTORCH_TASK}

	ERROR_RESP_EMPTY    = errors.New("resp empty error")
	ERROR_CONVERT_EMPTY = errors.New("convert empty error")
)

type StoreLink struct {
	ILinkage Linkage
}

func NewStoreLink(octopusRpc octopusclient.Octopus, modelArtsRpc modelartsservice.ModelArtsService, modelArtsImgRpc imagesservice.ImagesService, aCRpc hpcacclient.HpcAC, participant *models.StorelinkCenter) *StoreLink {
	switch participant.Type {
	case TYPE_OCTOPUS:
		linkStruct := NewOctopusLink(octopusRpc, participant.Name, participant.Id)
		return &StoreLink{ILinkage: linkStruct}
	case TYPE_MODELARTS:
		linkStruct := NewModelArtsLink(modelArtsRpc, modelArtsImgRpc, participant.Name, participant.Id, "")
		return &StoreLink{ILinkage: linkStruct}
	case TYPE_SHUGUANGAI:
		linkStruct := NewShuguangAi(aCRpc, participant.Name, participant.Id)
		return &StoreLink{ILinkage: linkStruct}
	case TYPE_SHUGUANGHPC:
		linkStruct := NewShuguangHpc(aCRpc, participant.Name, participant.Id)
		return &StoreLink{ILinkage: linkStruct}
	default:
		return nil
	}
}

func GetParticipants(dbEngin *gorm.DB) []*models.StorelinkCenter {
	var participants []*models.StorelinkCenter
	dbEngin.Raw("select * from storelink_center").Scan(&participants)
	return participants
}

func GetParticipantById(partId int64, dbEngin *gorm.DB) *models.StorelinkCenter {
	var participant models.StorelinkCenter
	dbEngin.Raw("select * from storelink_center where id = ?", partId).Scan(&participant)
	return &participant
}

func GetResourceTypes() []string {
	return resourceTypes
}

func GetModelTypes() []string {
	var mTypes []string
	for k, _ := range ModelTypeMap {
		mTypes = append(mTypes, k)
	}
	return mTypes
}

func GetModelNamesByType(t string) ([]string, error) {
	_, ok := ModelTypeMap[t]
	if !ok {
		return nil, errors.New("model type does not exist")
	}
	return ModelTypeMap[t], nil
}

func GetDatasetsNames(ctx context.Context, collectorMap map[string]collector.AiCollector) ([]string, error) {
	return Datasets, nil
}

func GetDatasetsNamesSync(ctx context.Context, collectorMap map[string]collector.AiCollector) ([]string, error) {
	var wg sync.WaitGroup
	var errCh = make(chan interface{}, len(collectorMap))
	var errs []interface{}
	var names []string
	var mu sync.Mutex
	colMap := collectorMap
	for s, col := range colMap {
		wg.Add(1)
		c := col
		id := s
		go func() {
			var ns []string
			specs, err := c.GetDatasetsSpecs(ctx)
			if err != nil {
				e := struct {
					err       error
					clusterId string
				}{
					err:       err,
					clusterId: id,
				}
				errCh <- e
				wg.Done()
				return
			}
			for _, spec := range specs {
				ns = append(ns, spec.Name)
			}
			if len(ns) == 0 {
				wg.Done()
				return
			}
			mu.Lock()
			if len(names) == 0 {
				names = ns
				wg.Done()
				mu.Unlock()
				return
			}
			names = common.IntersectString(names, ns)
			wg.Done()
			mu.Unlock()
		}()
	}
	wg.Wait()
	close(errCh)

	if len(errs) == len(colMap) {
		return nil, errors.New("get DatasetsNames failed")
	}

	for e := range errCh {
		errs = append(errs, e)
	}

	if len(errs) != 0 {
		var msg string
		for _, err := range errs {
			e := (err).(struct {
				err       error
				clusterId string
			})
			msg += fmt.Sprintf("clusterId: %v , error: %v \n", e.clusterId, e.err.Error())
		}
		return nil, errors.New(msg)
	}

	names = common.RemoveDuplicates(names)
	return names, nil
}

func GetAlgorithms(ctx context.Context, collectorMap map[string]collector.AiCollector, resourceType string, taskType string, dataset string) ([]string, error) {
	algorithm := AlgorithmsForDatasets[dataset]
	if len(algorithm) != 0 {
		return algorithm, nil
	}
	return nil, errors.New("not found")
}

func GetAlgorithmsSync(ctx context.Context, collectorMap map[string]collector.AiCollector, resourceType string, taskType string, dataset string) ([]string, error) {
	var names []string
	var wg sync.WaitGroup
	var errCh = make(chan interface{}, len(collectorMap))
	var errs []interface{}
	var mu sync.Mutex

	colMap := collectorMap
	for s, col := range colMap {
		wg.Add(1)
		c := col
		id := s
		go func() {
			var ns []string
			algorithms, err := c.GetAlgorithms(ctx)
			if err != nil {
				e := struct {
					err       error
					clusterId string
				}{
					err:       err,
					clusterId: id,
				}
				errCh <- e
				wg.Done()
				return
			}
			for _, algorithm := range algorithms {
				if algorithm.TaskType != taskType {
					continue
				}
				switch algorithm.Platform {
				case OCTOPUS:
					splitns := strings.Split(algorithm.Name, UNDERSCORE)
					if dataset != splitns[0] || len(splitns) == 1 {
						continue
					}
					ns = append(ns, splitns[1])
				case SHUGUANGAI:
					splitns := strings.Split(algorithm.Name, DASH)
					if dataset != splitns[0] || len(splitns) == 1 {
						continue
					}
					ns = append(ns, splitns[1])
				}
			}
			if len(ns) == 0 {
				wg.Done()
				return
			}
			mu.Lock()
			if len(names) == 0 {
				names = ns
				wg.Done()
				mu.Unlock()
				return
			}
			names = common.IntersectString(names, ns)
			wg.Done()
			mu.Unlock()
		}()
	}
	wg.Wait()
	close(errCh)

	for e := range errCh {
		errs = append(errs, e)
	}

	if len(errs) == len(colMap) {
		return nil, errors.New("get Algorithms failed")
	}

	if len(errs) != 0 {
		var msg string
		for _, err := range errs {
			e := (err).(struct {
				err       error
				clusterId string
			})
			msg += fmt.Sprintf("clusterId: %v , error: %v \n", e.clusterId, e.err.Error())
		}
		return nil, errors.New(msg)
	}

	names = common.RemoveDuplicates(names)
	return names, nil
}

func GetTaskTypes() []string {
	return taskTypes
}

func ConvertType(in interface{}, out interface{}, participant *models.StorelinkCenter) (interface{}, error) {

	switch (interface{})(in).(type) {
	case *types.GetResourceSpecsResp:
		return in, nil
	case *octopus.UploadImageResp:
		inresp := (interface{})(in).(*octopus.UploadImageResp)
		switch (interface{})(out).(type) {
		case *types.UploadLinkImageResp:
			resp := (interface{})(out).(*types.UploadLinkImageResp)
			resp.Success = inresp.Success
			if !resp.Success {
				resp.ErrorMsg = inresp.Error.Message
				return resp, nil
			}
			return resp, nil
		}
		return nil, nil

	case *octopus.DeleteImageResp:
		inresp := (interface{})(in).(*octopus.DeleteImageResp)
		switch (interface{})(out).(type) {
		case *types.DeleteLinkImageResp:
			resp := (interface{})(out).(*types.DeleteLinkImageResp)
			resp.Success = inresp.Success
			if !resp.Success {
				resp.ErrorMsg = inresp.Error.Message
				return resp, nil
			}
			return resp, nil
		}
		return nil, nil

	case *octopus.GetUserImageListResp:
		inresp := (interface{})(in).(*octopus.GetUserImageListResp)
		switch (interface{})(out).(type) {
		case *types.GetLinkImageListResp:
			resp := (interface{})(out).(*types.GetLinkImageListResp)
			resp.Success = inresp.Success
			if !resp.Success {
				resp.ErrorMsg = inresp.Error.Message
				resp.Images = nil
				return resp, nil
			}

			for _, v := range inresp.Payload.Images {
				var image types.ImageSl
				image.ImageId = v.Image.Id
				image.ImageName = v.Image.ImageName
				image.ImageStatus = OctImgStatus[v.Image.ImageStatus]
				resp.Images = append(resp.Images, &image)
			}
			return resp, nil
		}
		return nil, nil

	case *modelarts.ListReposDetailsResp:
		inresp := (interface{})(in).(*modelarts.ListReposDetailsResp)
		switch (interface{})(out).(type) {
		case *types.GetLinkImageListResp:
			resp := (interface{})(out).(*types.GetLinkImageListResp)
			if inresp.Errors != nil {
				resp.Success = false
				resp.ErrorMsg = inresp.Errors[0].ErrorMessage
				resp.Images = nil
				return resp, nil
			}

			resp.Success = true
			for _, v := range inresp.Items {
				for _, r := range v.Tags {
					var image types.ImageSl
					image.ImageId = v.Namespace + "/" + v.Name + ":" + r
					image.ImageName = v.Name
					image.ImageStatus = "created"
					resp.Images = append(resp.Images, &image)
				}
			}
			return resp, nil
		}
		return nil, nil

	case *hpcAC.GetImageListAiResp:
		inresp := (interface{})(in).(*hpcAC.GetImageListAiResp)
		switch (interface{})(out).(type) {
		case *types.GetLinkImageListResp:
			resp := (interface{})(out).(*types.GetLinkImageListResp)
			if inresp.Code == "0" {
				resp.Success = true
				for _, img := range inresp.Data {
					var image types.ImageSl
					image.ImageId = img.ImageId
					image.ImageName = img.Version
					image.ImageStatus = "created"
					resp.Images = append(resp.Images, &image)
				}
			} else {
				resp.Success = false
				resp.ErrorMsg = inresp.Msg
				resp.Images = nil
			}
			return resp, nil
		}
		return nil, nil

	case *octopus.CreateTrainJobResp:
		inresp := (interface{})(in).(*octopus.CreateTrainJobResp)
		switch (interface{})(out).(type) {
		case *types.SubmitLinkTaskResp:
			resp := (interface{})(out).(*types.SubmitLinkTaskResp)
			resp.Success = inresp.Success
			if !resp.Success {
				resp.ErrorMsg = inresp.Error.Message
				return resp, nil
			}

			resp.TaskId = inresp.Payload.JobId

			return resp, nil
		case *types.ScheduleResp:
			resp := (interface{})(out).(*types.ScheduleResp)
			return resp, nil
		}
		return nil, nil

	case *modelarts.CreateTrainingJobResp:
		inresp := (interface{})(in).(*modelarts.CreateTrainingJobResp)
		switch (interface{})(out).(type) {
		case *types.SubmitLinkTaskResp:
			resp := (interface{})(out).(*types.SubmitLinkTaskResp)
			if inresp.ErrorMsg != "" {
				resp.ErrorMsg = inresp.ErrorMsg
				resp.Success = false
				return resp, nil
			}
			resp.Success = true
			resp.TaskId = inresp.Metadata.Id

			return resp, nil
		}
		return nil, nil

	case *hpcAC.SubmitTaskAiResp:
		inresp := (interface{})(in).(*hpcAC.SubmitTaskAiResp)
		switch (interface{})(out).(type) {
		case *types.SubmitLinkTaskResp:
			resp := (interface{})(out).(*types.SubmitLinkTaskResp)
			if inresp.Code == "0" {
				resp.Success = true
				resp.TaskId = inresp.Data
			} else {
				resp.Success = false
				resp.ErrorMsg = inresp.Msg
			}
			return resp, nil
		case *types.ScheduleResp:
			resp := (interface{})(out).(*types.ScheduleResp)
			return resp, nil
		}
		return nil, nil

	case *hpcAC.SubmitJobResp:
		inresp := (interface{})(in).(*hpcAC.SubmitJobResp)
		switch (interface{})(out).(type) {
		case *types.SubmitLinkTaskResp:
			resp := (interface{})(out).(*types.SubmitLinkTaskResp)
			if inresp.Code == "0" {
				resp.Success = true
				resp.TaskId = inresp.Data
			} else {
				resp.Success = false
				resp.ErrorMsg = inresp.Msg
			}
			return resp, nil
		}
		return nil, nil

	case *octopus.GetTrainJobResp:
		inresp := (interface{})(in).(*octopus.GetTrainJobResp)
		switch (interface{})(out).(type) {
		case *types.GetLinkTaskResp:
			resp := (interface{})(out).(*types.GetLinkTaskResp)
			resp.Success = inresp.Success
			if !resp.Success {
				resp.ErrorMsg = inresp.Error.Message
				return resp, nil
			}

			var task types.TaskSl
			task.TaskId = inresp.Payload.TrainJob.Id
			task.TaskName = inresp.Payload.TrainJob.Name
			task.StartedAt = inresp.Payload.TrainJob.StartedAt
			task.CompletedAt = inresp.Payload.TrainJob.CompletedAt
			task.TaskStatus = inresp.Payload.TrainJob.Status

			resp.Task = &task
			return resp, nil
		}
		return nil, nil

	case *modelarts.JobResponse:
		inresp := (interface{})(in).(*modelarts.JobResponse)
		switch (interface{})(out).(type) {
		case *types.GetLinkTaskResp:
			resp := (interface{})(out).(*types.GetLinkTaskResp)
			if inresp.ErrorMsg != "" {
				resp.ErrorMsg = inresp.ErrorMsg
				resp.Success = false
				return resp, nil
			}
			resp.Success = true
			resp.Task = &types.TaskSl{}
			resp.Task.TaskId = inresp.Metadata.Id
			resp.Task.TaskName = inresp.Metadata.Name
			resp.Task.StartedAt = int64(inresp.Status.StartTime)
			resp.Task.CompletedAt = int64(inresp.Status.Duration)
			resp.Task.TaskStatus = inresp.Status.Phase

			return resp, nil
		}
		return nil, nil

	case *hpcAC.GetPytorchTaskResp:
		inresp := (interface{})(in).(*hpcAC.GetPytorchTaskResp)
		switch (interface{})(out).(type) {
		case *types.GetLinkTaskResp:
			resp := (interface{})(out).(*types.GetLinkTaskResp)
			if inresp.Code == "0" {
				resp.Success = true
				var task types.TaskSl
				task.TaskId = inresp.Data.Id
				task.TaskName = inresp.Data.TaskName
				task.TaskStatus = inresp.Data.Status
				task.StartedAt = timeutils.StringToUnixTime(inresp.Data.StartTime)
				task.CompletedAt = timeutils.StringToUnixTime(inresp.Data.EndTime)
				resp.Task = &task
			} else {
				resp.Success = false
				resp.ErrorMsg = inresp.Msg
				resp.Task = nil
			}

			return resp, nil
		}
		return nil, nil

	case *hpcAC.GetJobDetailResp:
		inresp := (interface{})(in).(*hpcAC.GetJobDetailResp)
		switch (interface{})(out).(type) {
		case *types.GetLinkTaskResp:
			resp := (interface{})(out).(*types.GetLinkTaskResp)
			if inresp.Code == "0" {
				resp.Success = true
				var task types.TaskSl
				task.TaskId = inresp.Data.JobId
				task.TaskName = inresp.Data.JobName
				task.TaskStatus = AcStatus[inresp.Data.JobStatus]
				task.StartedAt = timeutils.StringToUnixTime(inresp.Data.JobStartTime)
				task.CompletedAt = timeutils.StringToUnixTime(inresp.Data.JobEndTime)
				resp.Task = &task
			} else {
				resp.Success = false
				resp.ErrorMsg = inresp.Msg
				resp.Task = nil
			}

			return resp, nil
		}
		return nil, nil

	case *hpcAC.HistoryJobDetailResp:
		inresp := (interface{})(in).(*hpcAC.HistoryJobDetailResp)
		switch (interface{})(out).(type) {
		case *types.GetLinkTaskResp:
			resp := (interface{})(out).(*types.GetLinkTaskResp)
			if inresp.Code == "0" {
				resp.Success = true
				var task types.TaskSl
				task.TaskId = inresp.Data.JobId
				task.TaskName = inresp.Data.JobName
				task.TaskStatus = AcStatus[inresp.Data.JobState]
				task.StartedAt = timeutils.StringToUnixTime(inresp.Data.JobStartTime)
				task.CompletedAt = timeutils.StringToUnixTime(inresp.Data.JobEndTime)
				resp.Task = &task
			} else {
				resp.Success = false
				resp.ErrorMsg = inresp.Msg
				resp.Task = nil
			}

			return resp, nil
		}
		return nil, nil

	case *octopus.DeleteTrainJobResp:
		inresp := (interface{})(in).(*octopus.DeleteTrainJobResp)
		switch (interface{})(out).(type) {
		case *types.DeleteLinkTaskResp:
			resp := (interface{})(out).(*types.DeleteLinkTaskResp)
			resp.Success = inresp.Success
			if !resp.Success {
				resp.ErrorMsg = inresp.Error.Message
				return resp, nil
			}

			return resp, nil
		}
		return nil, nil

	case *modelarts.DeleteTrainingJobResp:
		inresp := (interface{})(in).(*modelarts.DeleteTrainingJobResp)
		switch (interface{})(out).(type) {
		case *types.DeleteLinkTaskResp:
			resp := (interface{})(out).(*types.DeleteLinkTaskResp)
			if inresp.ErrorMsg != "" {
				resp.ErrorMsg = inresp.ErrorMsg
				resp.Success = false
				return resp, nil
			}
			resp.Success = true
			return resp, nil
		}
		return nil, nil

	case *hpcAC.DeleteTaskAiResp:
		inresp := (interface{})(in).(*hpcAC.DeleteTaskAiResp)
		switch (interface{})(out).(type) {
		case *types.DeleteLinkTaskResp:
			resp := (interface{})(out).(*types.DeleteLinkTaskResp)
			if inresp.Code == "0" {
				resp.Success = true
			} else {
				resp.Success = false
				resp.ErrorMsg = inresp.Msg
			}
			return resp, nil
		}
		return nil, nil

	case *hpcAC.DeleteJobResp:
		inresp := (interface{})(in).(*hpcAC.DeleteJobResp)
		switch (interface{})(out).(type) {
		case *types.DeleteLinkTaskResp:
			resp := (interface{})(out).(*types.DeleteLinkTaskResp)
			if inresp.Code == "0" {
				resp.Success = true
			} else {
				resp.Success = false
				resp.ErrorMsg = inresp.Msg
			}
			return resp, nil
		}
		return nil, nil

	case *octopus.GetResourceSpecsResp:
		inresp := (interface{})(in).(*octopus.GetResourceSpecsResp)
		switch (interface{})(out).(type) {
		case *types.GetResourceSpecsResp:
			resp := (interface{})(out).(*types.GetResourceSpecsResp)
			resp.Success = inresp.Success
			if !resp.Success {
				resp.ResourceSpecs = nil
				return resp, nil
			}

			for _, spec := range inresp.TrainResourceSpecs {
				var respec types.ResourceSpecSl
				respec.SpecId = spec.Id
				respec.SpecName = spec.Name
				respec.ParticipantId = participant.Id
				respec.ParticipantName = participant.Name
				respec.SpecPrice = spec.Price
				resp.ResourceSpecs = append(resp.ResourceSpecs, &respec)
			}

			return resp, nil
		}
		return nil, nil

	case *modelarts.TrainingJobFlavorsResp:
		inresp := (interface{})(in).(*modelarts.TrainingJobFlavorsResp)
		switch (interface{})(out).(type) {
		case *types.GetResourceSpecsResp:
			resp := (interface{})(out).(*types.GetResourceSpecsResp)
			resp.Success = true

			if inresp.Flavors == nil {
				resp.Success = false
				resp.ResourceSpecs = nil
				return resp, nil
			}

			for _, spec := range inresp.Flavors {
				var respec types.ResourceSpecSl
				respec.SpecId = spec.FlavorId
				respec.SpecName = spec.FlavorName
				respec.ParticipantId = participant.Id
				respec.ParticipantName = participant.Name
				respec.SpecPrice = 0
				resp.ResourceSpecs = append(resp.ResourceSpecs, &respec)
			}

			return resp, nil
		}
		return nil, nil

	default:
		return nil, errors.New("type convert fail")
	}
}

func ConvertTypeOld[T any](in *T, participant *models.StorelinkCenter) (interface{}, error) {

	switch (interface{})(in).(type) {
	case *octopus.UploadImageResp:
		var resp types.UploadLinkImageResp
		inresp := (interface{})(in).(*octopus.UploadImageResp)
		resp.Success = inresp.Success
		if !resp.Success {
			resp.ErrorMsg = inresp.Error.Message
			return resp, nil
		}

		return resp, nil
	case *octopus.DeleteImageResp:
		var resp types.DeleteLinkImageResp
		inresp := (interface{})(in).(*octopus.DeleteImageResp)
		resp.Success = inresp.Success
		if !resp.Success {
			resp.ErrorMsg = inresp.Error.Message
			return resp, nil
		}

		return resp, nil

	case *octopus.GetUserImageListResp:
		var resp types.GetLinkImageListResp
		inresp := (interface{})(in).(*octopus.GetUserImageListResp)
		resp.Success = inresp.Success
		if !resp.Success {
			resp.ErrorMsg = inresp.Error.Message
			resp.Images = nil
			return resp, nil
		}

		for _, v := range inresp.Payload.Images {
			var image types.ImageSl
			image.ImageId = v.Image.Id
			image.ImageName = v.Image.ImageName
			image.ImageStatus = OctImgStatus[v.Image.ImageStatus]
			resp.Images = append(resp.Images, &image)
		}
		return resp, nil
	case *modelarts.ListReposDetailsResp:
		var resp types.GetLinkImageListResp
		inresp := (interface{})(in).(*modelarts.ListReposDetailsResp)

		if inresp.Errors != nil {
			resp.Success = false
			resp.ErrorMsg = inresp.Errors[0].ErrorMessage
			resp.Images = nil
			return resp, nil
		}

		resp.Success = true
		for _, v := range inresp.Items {
			for _, r := range v.Tags {
				var image types.ImageSl
				image.ImageId = v.Namespace + "/" + v.Name + ":" + r
				image.ImageName = v.Name
				image.ImageStatus = "created"
				resp.Images = append(resp.Images, &image)
			}
		}
		return resp, nil
	case *hpcAC.GetImageListAiResp:
		var resp types.GetLinkImageListResp
		inresp := (interface{})(in).(*hpcAC.GetImageListAiResp)

		if inresp.Code == "0" {
			resp.Success = true
			for _, img := range inresp.Data {
				var image types.ImageSl
				image.ImageId = img.ImageId
				image.ImageName = img.Version
				image.ImageStatus = "created"
				resp.Images = append(resp.Images, &image)
			}
		} else {
			resp.Success = false
			resp.ErrorMsg = inresp.Msg
			resp.Images = nil
		}
		return resp, nil

	case *octopus.CreateTrainJobResp:
		var resp types.SubmitLinkTaskResp
		inresp := (interface{})(in).(*octopus.CreateTrainJobResp)
		resp.Success = inresp.Success
		if !resp.Success {
			resp.ErrorMsg = inresp.Error.Message
			return resp, nil
		}

		resp.TaskId = inresp.Payload.JobId

		return resp, nil
	case *modelarts.CreateTrainingJobResp:
		var resp types.SubmitLinkTaskResp
		inresp := (interface{})(in).(*modelarts.CreateTrainingJobResp)

		if inresp.ErrorMsg != "" {
			resp.ErrorMsg = inresp.ErrorMsg
			resp.Success = false
			return resp, nil
		}
		resp.Success = true
		resp.TaskId = inresp.Metadata.Id

		return resp, nil
	case *hpcAC.SubmitTaskAiResp:
		var resp types.SubmitLinkTaskResp
		inresp := (interface{})(in).(*hpcAC.SubmitTaskAiResp)

		if inresp.Code == "0" {
			resp.Success = true
			resp.TaskId = inresp.Data
		} else {
			resp.Success = false
			resp.ErrorMsg = inresp.Msg
		}
		return resp, nil
	case *hpcAC.SubmitJobResp:
		var resp types.SubmitLinkTaskResp
		inresp := (interface{})(in).(*hpcAC.SubmitJobResp)
		if inresp.Code == "0" {
			resp.Success = true
			resp.TaskId = inresp.Data
		} else {
			resp.Success = false
			resp.ErrorMsg = inresp.Msg
		}
		return resp, nil
	case *octopus.GetTrainJobResp:
		var resp types.GetLinkTaskResp
		inresp := (interface{})(in).(*octopus.GetTrainJobResp)
		resp.Success = inresp.Success
		if !resp.Success {
			resp.ErrorMsg = inresp.Error.Message
			return resp, nil
		}

		var task types.TaskSl
		task.TaskId = inresp.Payload.TrainJob.Id
		task.TaskName = inresp.Payload.TrainJob.Name
		task.StartedAt = inresp.Payload.TrainJob.StartedAt
		task.CompletedAt = inresp.Payload.TrainJob.CompletedAt
		task.TaskStatus = inresp.Payload.TrainJob.Status

		resp.Task = &task
		return resp, nil
	case *modelarts.JobResponse:
		var resp types.GetLinkTaskResp
		inresp := (interface{})(in).(*modelarts.JobResponse)
		if inresp.ErrorMsg != "" {
			resp.ErrorMsg = inresp.ErrorMsg
			resp.Success = false
			return resp, nil
		}
		resp.Success = true
		resp.Task = &types.TaskSl{}
		resp.Task.TaskId = inresp.Metadata.Id
		resp.Task.TaskName = inresp.Metadata.Name
		resp.Task.StartedAt = int64(inresp.Status.StartTime)
		resp.Task.CompletedAt = int64(inresp.Status.Duration)
		resp.Task.TaskStatus = inresp.Status.Phase

		return resp, nil
	case *hpcAC.GetPytorchTaskResp:
		var resp types.GetLinkTaskResp
		inresp := (interface{})(in).(*hpcAC.GetPytorchTaskResp)
		if inresp.Code == "0" {
			resp.Success = true
			var task types.TaskSl
			task.TaskId = inresp.Data.Id
			task.TaskName = inresp.Data.TaskName
			task.TaskStatus = inresp.Data.Status
			task.StartedAt = timeutils.StringToUnixTime(inresp.Data.StartTime)
			task.CompletedAt = timeutils.StringToUnixTime(inresp.Data.EndTime)
			resp.Task = &task
		} else {
			resp.Success = false
			resp.ErrorMsg = inresp.Msg
			resp.Task = nil
		}

		return resp, nil
	case *hpcAC.GetJobDetailResp:
		var resp types.GetLinkTaskResp
		inresp := (interface{})(in).(*hpcAC.GetJobDetailResp)
		if inresp.Code == "0" {
			resp.Success = true
			var task types.TaskSl
			task.TaskId = inresp.Data.JobId
			task.TaskName = inresp.Data.JobName
			task.TaskStatus = AcStatus[inresp.Data.JobStatus]
			task.StartedAt = timeutils.StringToUnixTime(inresp.Data.JobStartTime)
			task.CompletedAt = timeutils.StringToUnixTime(inresp.Data.JobEndTime)
			resp.Task = &task
		} else {
			resp.Success = false
			resp.ErrorMsg = inresp.Msg
			resp.Task = nil
		}

		return resp, nil
	case *hpcAC.HistoryJobDetailResp:
		var resp types.GetLinkTaskResp
		inresp := (interface{})(in).(*hpcAC.HistoryJobDetailResp)
		if inresp.Code == "0" {
			resp.Success = true
			var task types.TaskSl
			task.TaskId = inresp.Data.JobId
			task.TaskName = inresp.Data.JobName
			task.TaskStatus = AcStatus[inresp.Data.JobState]
			task.StartedAt = timeutils.StringToUnixTime(inresp.Data.JobStartTime)
			task.CompletedAt = timeutils.StringToUnixTime(inresp.Data.JobEndTime)
			resp.Task = &task
		} else {
			resp.Success = false
			resp.ErrorMsg = inresp.Msg
			resp.Task = nil
		}

		return resp, nil
	case *octopus.DeleteTrainJobResp:
		var resp types.DeleteLinkTaskResp
		inresp := (interface{})(in).(*octopus.DeleteTrainJobResp)
		resp.Success = inresp.Success
		if !resp.Success {
			resp.ErrorMsg = inresp.Error.Message
			return resp, nil
		}

		return resp, nil
	case *modelarts.DeleteTrainingJobResp:
		var resp types.DeleteLinkTaskResp
		inresp := (interface{})(in).(*modelarts.DeleteTrainingJobResp)
		if inresp.ErrorMsg != "" {
			resp.ErrorMsg = inresp.ErrorMsg
			resp.Success = false
			return resp, nil
		}
		resp.Success = true
		return resp, nil
	case *hpcAC.DeleteTaskAiResp:
		var resp types.DeleteLinkTaskResp
		inresp := (interface{})(in).(*hpcAC.DeleteTaskAiResp)
		if inresp.Code == "0" {
			resp.Success = true
		} else {
			resp.Success = false
			resp.ErrorMsg = inresp.Msg
		}
		return resp, nil
	case *hpcAC.DeleteJobResp:
		var resp types.DeleteLinkTaskResp
		inresp := (interface{})(in).(*hpcAC.DeleteJobResp)
		if inresp.Code == "0" {
			resp.Success = true
		} else {
			resp.Success = false
			resp.ErrorMsg = inresp.Msg
		}
		return resp, nil
	case *octopus.GetResourceSpecsResp:
		var resp types.GetResourceSpecsResp
		inresp := (interface{})(in).(*octopus.GetResourceSpecsResp)
		resp.Success = inresp.Success
		if !resp.Success {
			resp.ResourceSpecs = nil
			return resp, nil
		}

		for _, spec := range inresp.TrainResourceSpecs {
			var respec types.ResourceSpecSl
			respec.SpecId = spec.Id
			respec.SpecName = spec.Name
			respec.ParticipantId = participant.Id
			respec.ParticipantName = participant.Name
			respec.SpecPrice = spec.Price
			resp.ResourceSpecs = append(resp.ResourceSpecs, &respec)
		}

		return resp, nil
	case *modelarts.TrainingJobFlavorsResp:
		var resp types.GetResourceSpecsResp
		resp.Success = true
		inresp := (interface{})(in).(*modelarts.TrainingJobFlavorsResp)
		if inresp.Flavors == nil {
			resp.Success = false
			resp.ResourceSpecs = nil
			return resp, nil
		}

		for _, spec := range inresp.Flavors {
			var respec types.ResourceSpecSl
			respec.SpecId = spec.FlavorId
			respec.SpecName = spec.FlavorName
			respec.ParticipantId = participant.Id
			respec.ParticipantName = participant.Name
			respec.SpecPrice = 0
			resp.ResourceSpecs = append(resp.ResourceSpecs, &respec)
		}

		return resp, nil
	default:
		return nil, errors.New("type convert fail")
	}
}
