package cn.myapps.scheduler;

import cn.myapps.authtime.common.dao.PersistenceUtils;
import cn.myapps.common.data.DataPackage;
import cn.myapps.common.model.task.Task;
import cn.myapps.common.model.task.TaskConstants;
import cn.myapps.designtime.common.service.DesignTimeServiceManager;
import cn.myapps.designtime.task.service.TaskDesignTimeService;
import cn.myapps.runtime.common.service.RunTimeServiceManager;
import cn.myapps.runtime.scheduler.ejb.TriggerProcess;
import cn.myapps.runtime.scheduler.ejb.TriggerVO;
import cn.myapps.runtime.scheduler.engine.job.IscriptTaskJob;
import cn.myapps.util.sequence.Sequence;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;

public class InitRuntimeScheduler {
    private static final Logger logger = LoggerFactory.getLogger(InitRuntimeScheduler.class);

    /**
     * 查询任务的时间间隔
     */
    private static final long INTERVAL = 60 * 1000L;
    /**
     * 初始化
     */
    public static void start(String application) {
        try {
            TaskDesignTimeService taskDesignTimeService = DesignTimeServiceManager.taskDesignTimeService();
            TriggerProcess triggerProcess = RunTimeServiceManager.triggerProcess(application);

            // 初始化触发器的状态，主要目的是还原非正常关闭服务器情况下状态标记就绪的触发器的状态
            triggerProcess.updateStandbyState2WaitingState();

            //定时任务列表
            DataPackage<Task> data = taskDesignTimeService.queryByNameOrDescript(application, "", 1, Integer.MAX_VALUE);

            //已经生成的脚本定时器任务
            Collection<TriggerVO> iscriptTriggers = triggerProcess.getTriggerByJobType(TriggerVO.JOB_TYPE_ISCRITP_TASK, 600000000 * 1000L);
            //转map
            Map<String, TriggerVO> triggerMap = new HashMap<>();
            for (TriggerVO trigger : iscriptTriggers) {
                if (application.equals(trigger.getApplicationId())) {
                    triggerMap.put(trigger.getTaskId(), trigger);
                }
            }

            //在现有的Task中,如果可以从TriggerMap拿到,那么的话就是
            TriggerVO newTrigger = null;
            for (Task task : data.getDatas()) {
                if (triggerMap.get(task.getId()) != null) {
                    TriggerVO triggerVO = triggerMap.get(task.getId());
                    //update
                    Calendar calendar = Calendar.getInstance();
                    IscriptTaskJob job = new IscriptTaskJob(task.getId(), !cn.myapps.common.util.StringUtil.isBlank(task.getApplicationid()) ? task.getApplicationid() : triggerVO.getApplicationId());
                    if (task.getPeriod() == TaskConstants.REPEAT_TYPE_NONE || task.getPeriod() == TaskConstants.REAPET_TYPE_NOTREAPET || task.getPeriod() == TaskConstants.REPEAT_TYPE_IMMEDIATE) {
                        job.setLoop(false);
                    } else {
                        job.setLoop(true);
                    }
                    newTrigger = new TriggerVO(job, calendar.getTimeInMillis());


                    triggerVO.setJobData(newTrigger.getJobData());
                    triggerVO.setDeadline(triggerVO.getDeadline());
                    triggerVO.setLastModifyDate(task.getModifyTime());

                    triggerProcess.doUpdate(triggerVO);
                    // 添加到任务队列
                    triggerMap.remove(task.getId());
                } else {
                    //insert
                    Calendar calendar = Calendar.getInstance();
                    calendar.setTime(task.getRunningTime());
                    IscriptTaskJob job = new IscriptTaskJob(task.getId(), task.getApplicationid());
                    if (task.getPeriod() == TaskConstants.REPEAT_TYPE_NONE || task.getPeriod() == TaskConstants.REAPET_TYPE_NOTREAPET || task.getPeriod() == TaskConstants.REPEAT_TYPE_IMMEDIATE) {
                        job.setLoop(false);
                    } else {
                        job.setLoop(true);
                    }
                    TriggerVO trigger = new TriggerVO(job, calendar.getTimeInMillis());
                    trigger.setId(Sequence.getSequence());
                    trigger.setApplicationId(task.getApplicationid());
                    trigger.setLastModifyDate(task.getModifyTime());
                    trigger.setRunTimes(0);
                    trigger.setTaskId(task.getId());
                    if (task.getStartupType() != TaskConstants.STARTUP_TYPE_AUTO) {
                        trigger.setState(TriggerVO.STATE_STOP);
                    }
                    triggerProcess.doCreate(trigger);
                    triggerMap.remove(task.getId());
                }
            }

            for (TriggerVO trigger : triggerMap.values()) {
                //删除剩余不存在的Task的Trigger
                triggerProcess.doRemove(trigger.getId());
            }
            //节点任务添加到队中
            Collection<TriggerVO> list = triggerProcess.getStandbyTrigger(INTERVAL);
            for (Iterator<TriggerVO> iterator = list.iterator(); iterator.hasNext(); ) {
                TriggerVO triggerVO = iterator.next();
                if (triggerVO.getJobType() != TriggerVO.JOB_TYPE_ISCRITP_TASK && application.equals(triggerVO.getApplicationId())) {
                    triggerVO.setState(TriggerVO.STATE_WAITING);
                    triggerProcess.doUpdate(triggerVO);
                }
            }
        } catch (Exception e) {
            logger.error("开始定时任务发生异常", e);
        } finally {
            try {
                PersistenceUtils.closeSessionAndConnection();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
