package com.dcs.hnyz.task;

import com.dcs.hnyz.domain.ActionConfig;
import com.dcs.hnyz.domain.DcsGroupTask;
import com.dcs.hnyz.domain.DcsGroupTaskLine;
import com.dcs.hnyz.domain.DcsRequestTask;
import com.dcs.hnyz.service.IDcsGroupTaskLineService;
import com.dcs.hnyz.service.IDcsGroupTaskService;
import com.dcs.hnyz.service.IDcsRequestTaskService;
import com.dcs.hnyz.service.impl.ActionConfigServiceImpl;
import org.apache.poi.ss.formula.functions.T;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

@EnableScheduling
@Component("RequestGroupTask")
public class RequestGroupTask {
    public static final Logger log = LoggerFactory.getLogger(RequestGroupTask.class);

    @Autowired
    private IDcsRequestTaskService requestTaskService;
    @Autowired
    private IDcsGroupTaskService groupTaskService;
    @Autowired
    private IDcsGroupTaskLineService groupTaskLineService;
    @Autowired
    private ActionConfigServiceImpl actionConfigService;
    public static Map<String, Thread> groupTaskThreadMap = new HashMap<>();


    @Scheduled(fixedDelay=5000)
    public void run(){
        DcsRequestTask requestTask = new DcsRequestTask();
        requestTask.setStatus(0);
        List<DcsRequestTask> requestTaskList = requestTaskService.selectDcsRequestTaskList(requestTask);
        requestTaskList.forEach(item->{
            Thread thread = groupTaskThreadMap.get(item.getLineCode());
            if (thread != null && thread.isAlive()) {
                return;
            }
            thread = new Thread(()->{
                runGroup(item);
                groupTaskThreadMap.remove(item.getLineCode());
            });
            thread.start();
            groupTaskThreadMap.put(item.getLineCode(), thread);
        });
    }

    private void runGroup(DcsRequestTask requestTask){
        String requestCode = requestTask.getRequestCode();
        try {
            log.info("====== 开始执行任务组：" + requestCode);
            updateTask(requestTask.getRequestId(), "开始执行", 1);
            DcsGroupTask groupTask = groupTaskService.selectDcsGroupTaskByGroupCode(requestCode);
            if (groupTask == null) {
                log.error(requestCode + "，组任务不存在");
                updateTask(requestTask.getRequestId(), "组任务已禁用", 3);
                return;
            }
            if (groupTask.getStatus() == 1) {
                log.error(requestCode + "，组任务已禁用");
                updateTask(requestTask.getRequestId(), "组任务已禁用", 3);
                return;
            }
            if (groupTask.getStatus() == 0) {
                runGroupAction(groupTask);
                updateTask(requestTask.getRequestId(), "已完成", 2);
            }
        }catch (Exception ex){
            log.error("执行"+requestCode+"组动作异常:", ex);
            updateTask(requestTask.getRequestId(), ex.getMessage(), 3);
        }
    }

    private void runGroupAction(DcsGroupTask groupTask) throws Exception {
        DcsGroupTaskLine groupTaskLine = new DcsGroupTaskLine();
        groupTaskLine.setGroupId(groupTask.getGroupId());
        List<DcsGroupTaskLine> groupTaskLineList = groupTaskLineService.selectDcsGroupTaskLineList(groupTaskLine);
        for(DcsGroupTaskLine line:groupTaskLineList){
            List<ActionConfig> actionConfigList = line.getActionConfigList();
            if(actionConfigList == null){
                throw new Exception(line.getActionName() + "不存在");
            }
            for (ActionConfig actionConfig:actionConfigList) {
                actionConfigService.triggerAction(actionConfig);
            }
        }
    }

    private void updateTask(long id, String rs, int status){
        DcsRequestTask requestTask = new DcsRequestTask();
        requestTask.setRequestId(id);
        requestTask.setRemark(rs);
        requestTask.setStatus(status);
        requestTaskService.updateDcsRequestTask(requestTask);
    }
}
