package com.ruoyi.platform.scheduling;

import com.ruoyi.platform.domain.*;
import com.ruoyi.platform.mapper.MachineLearnDao;
import com.ruoyi.platform.mapper.MachineLearnInsDao;
import com.ruoyi.platform.mapper.ResourceOccupyDao;
import com.ruoyi.platform.service.MachineLearnInsService;
import com.ruoyi.platform.service.ResourceOccupyService;
import com.ruoyi.system.api.constant.Constant;
import org.apache.commons.lang3.StringUtils;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;

@Component()
public class MLStatusTask {
    @Resource
    private MachineLearnInsService machineLearnInsService;
    @Resource
    private MachineLearnInsDao machineLearnInsDao;
    @Resource
    private MachineLearnDao machineLearnDao;
    @Resource
    private ResourceOccupyDao resourceOccupyDao;
    @Resource
    private ResourceOccupyService resourceOccupyService;

    private HashSet<Long> machineLearnIds = new HashSet<>();

    @Scheduled(cron = "0/10 * * * * ?") // 每10S执行一次
    public void executeMachineLearnInsStatus() {
        // 首先查到所有非终止态的实验实例
        List<MachineLearnIns> insList = machineLearnInsService.queryNotTerminated();

        // 去argo查询状态
        List<MachineLearnIns> updateList = new ArrayList<>();
        if (insList != null && insList.size() > 0) {
            for (MachineLearnIns ins : insList) {
                //当原本状态为null或非终止态时才调用argo接口
                try {
                    List<ResourceOccupy> resourceOccupys = resourceOccupyDao.getResourceOccupyByTask(Constant.TaskType_ML, ins.getMachineLearnId(), ins.getId(), null);
                    if (!resourceOccupys.isEmpty()) {
                        Long userId = resourceOccupys.get(0).getUserId();
                        if (resourceOccupyDao.getUserCredit(userId) <= 0) {
                            ins.setStatus(Constant.Failed);
                            machineLearnInsService.terminateMLIns(ins.getId());
                        } else {
                            ins = machineLearnInsService.queryStatusFromArgo(ins);
                            // 扣除积分
                            if (Constant.Running.equals(ins.getStatus())) {
                                resourceOccupyService.deducing(Constant.TaskType_ML, null, ins.getId(), null, null);
                            }
                            else if (Constant.Failed.equals(ins.getStatus()) || Constant.Terminated.equals(ins.getStatus())
                                    || Constant.Succeeded.equals(ins.getStatus())) {
                                resourceOccupyService.endDeduce(Constant.TaskType_ML, null, ins.getId(), null, null);
                            }
                        }
                    } else {
                        ins = machineLearnInsService.queryStatusFromArgo(ins);
                    }
                } catch (Exception e) {
                    ins.setStatus(Constant.Failed);
                    // 结束扣除积分
                    resourceOccupyService.endDeduce(Constant.TaskType_ML, null, ins.getId(), null, null);
                }
                // 线程安全的添加操作
                synchronized (machineLearnIds) {
                    machineLearnIds.add(ins.getMachineLearnId());
                }
                updateList.add(ins);
                if (updateList.size() > 0) {
                    for (MachineLearnIns machineLearnIns : updateList) {
                        machineLearnInsDao.update(machineLearnIns);
                    }
                }
            }
        }
    }

    @Scheduled(cron = "0/10 * * * * ?") // / 每30S执行一次
    public void executeMachineLearn() {
        if (machineLearnIds.isEmpty()) {
            return;
        }
        // 存储需要更新的实验对象列表
        List<MachineLearn> updateMLs = new ArrayList<>();
        Iterator<Long> iterator1 = machineLearnIds.iterator();

        while (iterator1.hasNext()) {
            Long machineLearnId = iterator1.next();
            // 获取当前实验的所有实例列表
            List<MachineLearnIns> insList = machineLearnInsDao.getByMachineLearnId(machineLearnId);
            List<String> statusList = new ArrayList<>();
            // 更新实验状态列表
            for (int i = 0; i < insList.size(); i++) {
                statusList.add(insList.get(i).getStatus());
            }
            String subStatus = statusList.toString().substring(1, statusList.toString().length() - 1);
            MachineLearn machineLearn = machineLearnDao.getMachineLearnById(machineLearnId);
            if (machineLearn == null) {
                iterator1.remove();
            } else {
                if (!StringUtils.equals(machineLearn.getStatusList(), subStatus)) {
                    machineLearn.setStatusList(subStatus);
                    updateMLs.add(machineLearn);
                    machineLearnDao.edit(machineLearn);
                }
            }
        }

        if (!updateMLs.isEmpty()) {
            // 使用Iterator进行安全的删除操作
            Iterator<Long> iterator = machineLearnIds.iterator();
            while (iterator.hasNext()) {
                Long machineLearnId = iterator.next();
                for (MachineLearn machineLearn : updateMLs) {
                    if (machineLearn.getId().equals(machineLearnId)) {
                        iterator.remove();
                    }
                }
            }
        }
    }
}
