package hpc

import (
	"context"
	"errors"
	clientCore "gitlink.org.cn/JointCloud/pcm-coordinator/client"
	"gitlink.org.cn/JointCloud/pcm-coordinator/pkg/constants"
	"gitlink.org.cn/JointCloud/pcm-coordinator/pkg/models"
	"k8s.io/apimachinery/pkg/util/json"
	"math/rand"
	"time"

	"gitlink.org.cn/JointCloud/pcm-coordinator/internal/svc"
	"gitlink.org.cn/JointCloud/pcm-coordinator/internal/types"

	"github.com/zeromicro/go-zero/core/logx"
)

type CommitHpcTaskLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewCommitHpcTaskLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CommitHpcTaskLogic {
	return &CommitHpcTaskLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *CommitHpcTaskLogic) CommitHpcTask(req *types.CommitHpcTaskReq) (resp *types.CommitHpcTaskResp, err error) {

	// 构建主任务结构体
	taskModel := models.Task{
		Name:            req.Name,
		Description:     req.Description,
		Status:          constants.Saved,
		Strategy:        0,
		SynergyStatus:   0,
		CommitTime:      time.Now(),
		AdapterTypeDict: "2",
	}

	// 保存任务数据到数据库
	tx := l.svcCtx.DbEngin.Create(&taskModel)
	if tx.Error != nil {
		return nil, tx.Error
	}

	var clusterIds []int64
	l.svcCtx.DbEngin.Raw("SELECT id FROM `t_cluster` where adapter_id in ? and label = ?", req.AdapterIds, req.ClusterType).Scan(&clusterIds)
	if len(clusterIds) == 0 || clusterIds == nil {
		resp.Code = 400
		resp.Msg = "no cluster found"
		return resp, nil
	}

	var clusterName string
	var adapterId int64
	var adapterName string
	clusterId := clusterIds[rand.Intn(len(clusterIds))]
	l.svcCtx.DbEngin.Raw("SELECT nickname FROM `t_cluster` where id = ?", clusterId).Scan(&clusterName)
	l.svcCtx.DbEngin.Raw("SELECT adapter_id FROM `t_cluster` where id = ?", clusterId).Scan(&adapterId)
	l.svcCtx.DbEngin.Raw("SELECT name FROM `t_adapter` where id = ?", adapterId).Scan(&adapterName)
	if len(adapterName) == 0 || adapterName == "" {
		return nil, errors.New("no corresponding adapter found")
	}
	env, _ := json.Marshal(req.Environment)

	hpcInfo := models.TaskHpc{
		TaskId:      taskModel.Id,
		AdapterId:   uint(adapterId),
		AdapterName: adapterName,
		ClusterId:   uint(clusterId),
		ClusterName: clusterName,
		Name:        taskModel.Name,
		Status:      "Saved",
		CmdScript:   req.CmdScript,
		StartTime:   time.Now().String(),
		CardCount:   req.CardCount,
		WorkDir:     req.WorkDir,
		WallTime:    req.WallTime,
		AppType:     req.AppType,
		AppName:     req.AppName,
		Queue:       req.Queue,
		SubmitType:  req.SubmitType,
		NNode:       req.NNode,
		StdOutFile:  req.StdOutFile,
		StdErrFile:  req.StdErrFile,
		StdInput:    req.StdInput,
		DeletedFlag: 0,
		CreatedBy:   0,
		CreatedTime: time.Now(),
		UpdatedBy:   0,
		UpdatedTime: time.Now(),
		Environment: string(env),
	}

	tx = l.svcCtx.DbEngin.Create(&hpcInfo)
	if tx.Error != nil {
		return nil, tx.Error
	}
	noticeInfo := clientCore.NoticeInfo{
		AdapterId:   adapterId,
		AdapterName: adapterName,
		ClusterId:   clusterId,
		ClusterName: clusterName,
		NoticeType:  "create",
		TaskName:    req.Name,
		Incident:    "任务创建中",
		CreatedTime: time.Now(),
	}
	result := l.svcCtx.DbEngin.Table("t_notice").Create(&noticeInfo)
	if result.Error != nil {
		logx.Errorf("Task creation failure, err: %v", result.Error)
	}
	// todo mq task manage
	//reqMessage, err := json.Marshal(mqInfo)
	//if err != nil {
	//	logx.Error(err)
	//	return nil, err
	//}
	//publish := l.svcCtx.RedisClient.Publish(context.Background(), mqInfo.TaskType, reqMessage)
	//if publish.Err() != nil {
	//	return nil, publish.Err()
	//}
	resp = &types.CommitHpcTaskResp{
		Code:   200,
		Msg:    "success",
		TaskId: taskModel.Id,
	}
	return resp, nil
}
