package com.hzya.frame.web.quartz;

import com.alibaba.fastjson.JSONObject;
import com.hzya.frame.sysnew.integtationTask.IIntegrationTaskCacheableService;
import com.hzya.frame.sysnew.integtationTask.entity.IntegrationTaskEntity;
import com.hzya.frame.sysnew.integtationTaskLiving.entity.IntegrationTaskLivingEntity;
import com.hzya.frame.web.exception.BaseSystemException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.quartz.*;
import org.quartz.impl.triggers.CronTriggerImpl;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.text.ParseException;

/**
 * @Content 任务计划操作工具类
 * @Author 👻👻👻👻👻👻👻👻👻👻 gjh
 * @Date 2021-5-7 14:13
 * @Version 1.0
 */
@Component()
@Lazy(value = false)
public class QuartzJobFactoryUtils {
    private static final Logger logger = LogManager.getLogger(QuartzJobFactoryUtils.class);

    /**
     * 定时器任务工厂类注入，因设置静态变量，通过set方法注入
     */
    private static SchedulerFactoryBean schedulerFactoryBean;

    private static IIntegrationTaskCacheableService iIntegrationTaskCacheableService;

    @Resource
    public void setiIntegrationTaskCacheableService(IIntegrationTaskCacheableService iIntegrationTaskCacheableService) {
        QuartzJobFactoryUtils.iIntegrationTaskCacheableService = iIntegrationTaskCacheableService;
    }

    @Resource
    public void setSchedulerFactoryBean(SchedulerFactoryBean schedulerFactoryBean) {
        QuartzJobFactoryUtils.schedulerFactoryBean = schedulerFactoryBean;
    }

    private Scheduler scheduler = null;

    /****
     * @Content:根据任务名称，获取TriggerKey
     * @Author 👻👻👻👻👻👻👻👻 gjh
     * @Date 2021-5-7 14:49
     * @Param [job]
     * @return org.quartz.TriggerKey
     **/
    private static TriggerKey getTriggerKey(String job_name, String job_code) {

        return TriggerKey.triggerKey(job_name, job_code);
    }

    private boolean validateJob() {
        boolean flag = true;
        if (null == null) {

        }

        return true;
    }

    /****
     * @Content:获取ScheduleJobEntity对象，如果不传入任务名称，分组名称，返回整个对象
     * @Author 👻👻👻👻👻👻👻👻 gjh
     * @Date 2021-5-7 14:55
     * @Param [jobName, jobGroup]
     * @return org.quartz.Scheduler
     **/
    private static Scheduler getScheduler(String jobName, String jobCode) throws SchedulerException {

        if ("".equalsIgnoreCase(jobName) || null == jobName || "".equalsIgnoreCase(jobCode) || null == jobCode) {
            return schedulerFactoryBean.getScheduler();
        } else {
            TriggerKey triggerKey = getTriggerKey(jobName, jobCode);
            return schedulerFactoryBean.getScheduler();
        }
    }


    /****
     * @Content:创建或者修改一个任务
     * @Author 👻👻👻👻👻👻👻👻 gjh
     * @Date 2021-5-7 14:49
     * @Param [job]
     * @return void
     **/
    public static void createJob(JSONObject job) throws SchedulerException, ParseException {
        String integrationTaskId = job.getString("integrationTaskId");
        IntegrationTaskEntity integrationTaskEntity = iIntegrationTaskCacheableService.getIntegrationTaskEntity(integrationTaskId);
        logger.info("开始创建/更新任务：jobName" + integrationTaskEntity.getTaskName());
        Scheduler scheduler = schedulerFactoryBean.getScheduler();
        TriggerKey triggerKey = new TriggerKey(integrationTaskEntity.getTaskName(), integrationTaskEntity.getTaskCode());
        CronTriggerImpl trigger = (CronTriggerImpl) scheduler.getTrigger(triggerKey);
        if (trigger == null) {
            // 创建CronTrigger，设置错过触发时的处理策略为不执行，确保只有上次任务执行完毕后，才会进行下一次的调度
            Trigger cronTrigger = TriggerBuilder.newTrigger()
                    .withIdentity(integrationTaskEntity.getTaskName(), integrationTaskEntity.getTaskCode())
                    .withSchedule(CronScheduleBuilder.cronSchedule(integrationTaskEntity.getTaskCron())
                            .withMisfireHandlingInstructionDoNothing()
                    )
                    .build();
            JobDetail jobDetail = JobBuilder.newJob(com.hzya.frame.web.quartz.QuartzJobFactory.class).withIdentity(integrationTaskEntity.getTaskName(), integrationTaskEntity.getTaskCode()).build();
            jobDetail.getJobDataMap().put("job", job);
            scheduler.scheduleJob(jobDetail, cronTrigger);
            logger.info("添加" + integrationTaskEntity.getTaskName() + "任务成功");
        } else {
            //修改策略
            trigger.setCronExpression(integrationTaskEntity.getTaskCron());
            scheduler.rescheduleJob(triggerKey, trigger);
            logger.info("修改" + integrationTaskEntity.getTaskName() + "任务成功");
        }

    }


    /****
     * @Content:启动定时任务
     * @Author 👻👻👻👻👻👻👻👻 gjh
     * @Date 2021-5-20 8:09
     * @Param [job]
     * @return void
     **/
    public static void startTimerTask(JSONObject job) {
        String jobName = job.getString("jobName");
        String jobCode = job.getString("jobCode");
        try {
            //获取触发器标识
            TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobCode);
            //获取触发器trigger
            Scheduler scheduler = schedulerFactoryBean.getScheduler();
            scheduler.start();
        } catch (SchedulerException e) {
            logger.error("启动任务失败！当前任务" + jobName, e);
            e.printStackTrace();
        }
    }

    /**
     * 是否启动
     *
     * @return
     * @throws org.quartz.SchedulerException
     */
    public boolean isStartTimerTisk() throws SchedulerException {
        return this.scheduler.isStarted();
    }

    /**
     * 是否关闭
     *
     * @return
     * @throws org.quartz.SchedulerException
     */
    public boolean isShutDownTimerTisk() throws SchedulerException {
        return this.scheduler.isShutdown();
    }

    /****
     * @Content: 停止一个定时作业
     * @Author 👻👻👻👻👻👻👻👻 gjh
     * @Date 2021-5-7 15:09
     * @Param [job]
     * @return void
     **/
    public static void pauseJob(JSONObject job) {
        String jobName = job.getString("jobName");
        String jobCode = job.getString("jobCode");
        JobKey jobKey = JobKey.jobKey(jobName, jobCode);
        //获取触发器trigger
        Scheduler scheduler = schedulerFactoryBean.getScheduler();
        try {
            scheduler.pauseJob(jobKey);
        } catch (Exception e) {
            e.printStackTrace();
            throw new BaseSystemException("停止任务：" + jobName + "失败！失败原因：" + e.getMessage());
        }
    }

    /****
     * @Content: 恢复一个任务
     * @Author 👻👻👻👻👻👻👻👻 gjh
     * @Date 2021-5-7 15:10
     * @Param [job]
     * @return void
     **/
    public static void resumeJob(JSONObject job) {
        String jobName = job.getString("jobName");
        String jobCode = job.getString("jobCode");
        JobKey jobKey = JobKey.jobKey(jobName, jobCode);
        Scheduler scheduler = schedulerFactoryBean.getScheduler();
        try {
            scheduler.resumeJob(jobKey);
        } catch (Exception e) {
            e.printStackTrace();
            throw new BaseSystemException("恢复任务：" + jobName + "失败！失败原因：" + e.getMessage());
        }

    }

    /****
     * @Content:删除指定的job
     * @Author 👻👻👻👻👻👻👻👻 gjh
     * @Date 2021-5-7 15:11
     * @Param [job]
     * @return boolean
     **/
    public static boolean deleteJob(JSONObject job) {
        boolean flag = false;
        String jobName = job.getString("jobName");
        String jobCode = job.getString("jobCode");
        try {
            JobKey jobKey = JobKey.jobKey(jobName, jobCode);
            Scheduler scheduler = schedulerFactoryBean.getScheduler();
            flag = scheduler.deleteJob(jobKey);
        } catch (Exception e) {
            e.printStackTrace();
            throw new BaseSystemException("删除任务：" + jobName + "失败！失败原因：" + e.getMessage());
        }
        return flag;
    }

    /****
     * @Content: 停止一个触发器
     * @Author 👻👻👻👻👻👻👻👻 gjh
     * @Date 2021-5-20 8:56
     * @Param [job]
     * @return void
     **/
    public static void pauseTrigger(JSONObject job) {
        String jobName = job.getString("jobName");
        String jobCode = job.getString("jobCode");
        try {
            TriggerKey triggerKey = getTriggerKey(jobName, jobCode);
            Scheduler scheduler = schedulerFactoryBean.getScheduler();
            //停止触发器
            scheduler.pauseTrigger(triggerKey);
        } catch (SchedulerException e) {
            throw new BaseSystemException("停止任务：" + jobName + "失败！失败原因：" + e.getMessage());
        }
    }

    /**
     * 重启触发器
     */
    public static void resumeTrigger(JSONObject job) {
        String jobName = job.getString("jobName");
        String jobCode = job.getString("jobCode");
        try {
            TriggerKey triggerKey = getTriggerKey(jobName, jobCode);
            Scheduler scheduler = schedulerFactoryBean.getScheduler();

            scheduler.resumeTrigger(triggerKey);//重启触发器
        } catch (SchedulerException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 移除触发器
     *
     * @return
     */
    public boolean removeTrigdger(JSONObject job) {
        String jobName = job.getString("jobName");
        String jobCode = job.getString("jobCode");
        try {
            TriggerKey triggerKey = getTriggerKey(jobName, jobCode);
            Scheduler scheduler = schedulerFactoryBean.getScheduler();

            scheduler.pauseTrigger(triggerKey);//停止触发器
            return scheduler.unscheduleJob(triggerKey);//移除触发器
        } catch (SchedulerException e) {
            throw new RuntimeException(e);
        }
    }


}
