package com.ruoyi.platform.scheduling;

import com.ruoyi.platform.domain.Ray;
import com.ruoyi.platform.domain.RayIns;
import com.ruoyi.platform.mapper.RayDao;
import com.ruoyi.platform.mapper.RayInsDao;
import com.ruoyi.platform.mapper.ResourceOccupyDao;
import com.ruoyi.platform.service.RayInsService;
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 RayInsStatusTask {

    @Resource
    private RayInsService rayInsService;
    @Resource
    private RayInsDao rayInsDao;
    @Resource
    private RayDao rayDao;
    @Resource
    private ResourceOccupyDao resourceOccupyDao;
    @Resource
    private ResourceOccupyService resourceOccupyService;

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

    @Scheduled(cron = "0/10 * * * * ?") // 每10S执行一次
    public void executeRayInsStatus() {
        List<RayIns> rayInsList = rayInsService.queryByRayInsIsNotTerminated();

        // 去argo查询状态
        List<RayIns> updateList = new ArrayList<>();
        if (rayInsList != null && rayInsList.size() > 0) {
            for (RayIns rayIns : rayInsList) {
                //当原本状态为null或非终止态时才调用argo接口
                try {
                    Long userId = resourceOccupyDao.getResourceOccupyByTask(Constant.TaskType_Ray, rayIns.getRayId(), rayIns.getId(), null).get(0).getUserId();
                    if (resourceOccupyDao.getUserCredit(userId) <= 0) {
                        rayIns.setStatus(Constant.Failed);
                        rayInsService.terminateRayIns(rayIns.getId());
                    } else {
                        rayIns = rayInsService.queryStatusFromArgo(rayIns);
                        // 扣除积分
                        if (Constant.Running.equals(rayIns.getStatus())) {
                            resourceOccupyService.deducing(Constant.TaskType_Ray, null, rayIns.getId(), null, null);
                        }
                        else if (Constant.Failed.equals(rayIns.getStatus()) || Constant.Terminated.equals(rayIns.getStatus())
                                || Constant.Succeeded.equals(rayIns.getStatus())) {
                            resourceOccupyService.endDeduce(Constant.TaskType_Ray, null, rayIns.getId(), null, null);
                        }
                    }
                } catch (Exception e) {
                    System.out.println(e.getMessage());
                    rayIns.setStatus(Constant.Failed);
                    // 结束扣除积分
                    resourceOccupyService.endDeduce(Constant.TaskType_Ray, null, rayIns.getId(), null, null);
                }
                // 线程安全的添加操作
                synchronized (rayIds) {
                    rayIds.add(rayIns.getRayId());
                }
                updateList.add(rayIns);
            }
            if (updateList.size() > 0) {
                for (RayIns rayIns : updateList) {
                    rayInsDao.update(rayIns);
                }
            }
        }
    }

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

        while (iterator1.hasNext()) {
            Long rayId = iterator1.next();
            // 获取当前实验的所有实例列表
            List<RayIns> insList = rayInsDao.getByRayId(rayId);
            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);
            Ray ray = rayDao.getRayById(rayId);
            if (ray == null) {
                iterator1.remove();
            } else {
                if (!StringUtils.equals(ray.getStatusList(), subStatus)) {
                    ray.setStatusList(subStatus);
                    updateRays.add(ray);
                    rayDao.edit(ray);
                }
            }
        }

        if (!updateRays.isEmpty()) {
            // 使用Iterator进行安全的删除操作
            Iterator<Long> iterator = rayIds.iterator();
            while (iterator.hasNext()) {
                Long rayId = iterator.next();
                for (Ray ray : updateRays) {
                    if (ray.getId().equals(rayId)) {
                        iterator.remove();
                    }
                }
            }
        }
    }
}
