package com.ruoyi.platform.scheduling;

import com.ruoyi.platform.domain.ActiveLearn;
import com.ruoyi.platform.domain.ActiveLearnIns;
import com.ruoyi.platform.mapper.ActiveLearnDao;
import com.ruoyi.platform.mapper.ActiveLearnInsDao;
import com.ruoyi.platform.mapper.ResourceOccupyDao;
import com.ruoyi.platform.service.ActiveLearnInsService;
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 ActiveLearnInsStatusTask {

    @Resource
    private ActiveLearnInsService activeLearnInsService;
    @Resource
    private ActiveLearnInsDao activeLearnInsDao;
    @Resource
    private ActiveLearnDao activeLearnDao;
    @Resource
    private ResourceOccupyDao resourceOccupyDao;
    @Resource
    private ResourceOccupyService resourceOccupyService;

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

    @Scheduled(cron = "0/10 * * * * ?") // 每10S执行一次
    public void executeActiveLearnInsStatus() {
        List<ActiveLearnIns> activeLearnInsList = activeLearnInsService.queryActiveLearnInsIsNotTerminated();

        // 去argo查询状态
        List<ActiveLearnIns> updateList = new ArrayList<>();
        if (activeLearnInsList != null && activeLearnInsList.size() > 0) {
            for (ActiveLearnIns activeLearnIns : activeLearnInsList) {
                //当原本状态为null或非终止态时才调用argo接口
                try {
                    Long userId = resourceOccupyDao.getResourceOccupyByTask(Constant.TaskType_ActiveLearn, activeLearnIns.getActiveLearnId(), activeLearnIns.getId(), null).get(0).getUserId();
                    if (resourceOccupyDao.getUserCredit(userId) <= 0) {
                        activeLearnIns.setStatus(Constant.Failed);
                        activeLearnInsService.terminateActiveLearnIns(activeLearnIns.getId());
                    } else {
                        activeLearnIns = activeLearnInsService.queryStatusFromArgo(activeLearnIns);
                        // 扣除积分
                        if (Constant.Running.equals(activeLearnIns.getStatus())) {
                            resourceOccupyService.deducing(Constant.TaskType_ActiveLearn, null, activeLearnIns.getId(), null, null);
                        }
                        else if (Constant.Failed.equals(activeLearnIns.getStatus()) || Constant.Terminated.equals(activeLearnIns.getStatus())
                                || Constant.Succeeded.equals(activeLearnIns.getStatus())) {
                            resourceOccupyService.endDeduce(Constant.TaskType_ActiveLearn, null, activeLearnIns.getId(), null, null);
                        }
                    }
                } catch (Exception e) {
                    activeLearnIns.setStatus(Constant.Failed);
                    // 结束扣除积分
                    resourceOccupyService.endDeduce(Constant.TaskType_ActiveLearn, null, activeLearnIns.getId(), null, null);
                }
                // 线程安全的添加操作
                synchronized (activeLearnIds) {
                    activeLearnIds.add(activeLearnIns.getActiveLearnId());
                }
                updateList.add(activeLearnIns);
            }
            if (updateList.size() > 0) {
                for (ActiveLearnIns activeLearnIns : updateList) {
                    activeLearnInsDao.update(activeLearnIns);
                }
            }
        }
    }

    @Scheduled(cron = "0/10 * * * * ?") // / 每30S执行一次
    public void executeActiveLearnStatus() {
        if (activeLearnIds.isEmpty()) {
            return;
        }
        // 存储需要更新的实验对象列表
        List<ActiveLearn> updateActiveLearns = new ArrayList<>();
        Iterator<Long> iterator1 = activeLearnIds.iterator();
        while (iterator1.hasNext()) {
            Long activeLearnId = iterator1.next();
            // 获取当前实验的所有实例列表
            List<ActiveLearnIns> insList = activeLearnInsDao.getByActiveLearnId(activeLearnId);
            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);
            ActiveLearn activeLearn = activeLearnDao.getActiveLearnById(activeLearnId);
            if (activeLearn == null) {
                iterator1.remove();
            } else {
                if (!StringUtils.equals(activeLearn.getStatusList(), subStatus)) {
                    activeLearn.setStatusList(subStatus);
                    updateActiveLearns.add(activeLearn);
                    activeLearnDao.edit(activeLearn);
                }
            }
        }

        if (!updateActiveLearns.isEmpty()) {
            // 使用Iterator进行安全的删除操作
            Iterator<Long> iterator = activeLearnIds.iterator();
            while (iterator.hasNext()) {
                Long activeLearnId = iterator.next();
                for (ActiveLearn activeLearn : updateActiveLearns) {
                    if (activeLearn.getId().equals(activeLearnId)) {
                        iterator.remove();
                    }
                }
            }
        }
    }
}
