/*

 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 participantservicelogic

import (
	"context"
	"fmt"
	"github.com/pkg/errors"
	models2 "gitlink.org.cn/JointCloud/pcm-coordinator/pkg/models"
	"gitlink.org.cn/JointCloud/pcm-coordinator/pkg/utils"
	"gitlink.org.cn/JointCloud/pcm-coordinator/rpc/internal/svc"
	"gitlink.org.cn/JointCloud/pcm-coordinator/rpc/pcmCore"
	"gorm.io/gorm"
	"time"

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

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

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

// ReportAvailable 监控数据上报
func (l *ReportAvailableLogic) ReportAvailable(in *pcmCore.ParticipantAvailReq) (*pcmCore.ParticipantResp, error) {
	db := l.svcCtx.DbEngin.Begin()
	// 执行回滚或者提交操作
	defer func() {
		if p := recover(); p != nil {
			db.Rollback()
			logx.Error(p)
		} else if db.Error != nil {
			logx.Info("rollback")
			db.Rollback()
		} else {
			db = db.Commit()
			logx.Info("commit success")
		}
	}()
	//判断Participant静态信息是否存在
	participantPhyInfo := &models2.ScParticipantPhyInfo{}
	participantPhyInfo.Id = in.ParticipantId
	if in.ParticipantId == 0 {
		return &pcmCore.ParticipantResp{
			Code: 500,
			Msg:  fmt.Sprintf("ParticipantInfo Does not exist, please check participantPhyId: %d", in.ParticipantId),
		}, nil
	}
	if errors.Is(db.Take(&participantPhyInfo).Error, gorm.ErrRecordNotFound) {
		return &pcmCore.ParticipantResp{
			Code: 500,
			Msg:  fmt.Sprintf("ParticipantInfo Does not exist, please check participantPhyId: %d", in.ParticipantId),
		}, nil
	}

	participantAvailInfo := &models2.ScParticipantAvailInfo{}
	utils.Convert(in, participantAvailInfo)
	if in.Id == 0 {
		participantAvailInfo.Id = utils.GenSnowflakeID()
	}
	participantAvailInfo.CreatedTime = time.Now()
	//保存participant动态信息
	result := db.Save(&participantAvailInfo)
	//保存节点信息
	nodeList := make([]*models2.ScNodeAvailInfo, 0)
	for _, info := range in.NodeAvailInfo {
		nodeInfo := &models2.ScNodeAvailInfo{}
		utils.Convert(info, nodeInfo)
		nodeInfo.CreatedTime = time.Now()
		nodeInfo.ParticipantId = participantAvailInfo.ParticipantId
		if nodeInfo.Id == 0 {
			nodeInfo.Id = utils.GenSnowflakeID()
		}
		nodeList = append(nodeList, nodeInfo)
	}
	result = db.Save(&nodeList)
	if result.Error != nil {
		logx.Errorf("orm err:", result.Error)
		return &pcmCore.ParticipantResp{
			Code: 500,
			Msg:  fmt.Sprintf("Save participantAvailInfo error %s", result.Error),
		}, nil
	}

	return &pcmCore.ParticipantResp{
		Code: 200,
		Msg:  "ok",
	}, nil
}
