package com.ssm.core.utils;


import com.ssm.task.MyJobFactory;
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import org.quartz.impl.triggers.SimpleTriggerImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

//
@Component
@Slf4j
public class QuartzManage {

    private static SchedulerFactory factory = new StdSchedulerFactory();

    private static MyJobFactory myJobFactory;

    @Autowired
    private MyJobFactory myJobFactory2;

    //注入Scheduler 走持久化
    @Autowired
    private Scheduler scheduler;


    @PostConstruct
    public void init(){
        myJobFactory = myJobFactory2;
    }

    public  void addTask(String taskName, String taskGroupName, String triggerName, String triggerGroupName, Class cls, String cron, String method) {
        try {
            MethodInvokingJobDetailFactoryBean jobDetailFactoryBean = new MethodInvokingJobDetailFactoryBean();
            jobDetailFactoryBean.setConcurrent(true);
            jobDetailFactoryBean.setName(taskName);
            jobDetailFactoryBean.setGroup(taskGroupName);
            jobDetailFactoryBean.setTargetClass(cls);
            jobDetailFactoryBean.setTargetMethod(method);
            jobDetailFactoryBean.setConcurrent(false);
            jobDetailFactoryBean.afterPropertiesSet();
            JobDetail jobDetail = jobDetailFactoryBean.getObject();// 动态

            // 表达式调度构建器
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cron);
            // 按新的cronExpression表达式构建一个新的trigger
            CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(triggerName, triggerGroupName)
                    .withSchedule(scheduleBuilder).build();
//            Scheduler scheduler = factory.getScheduler();
            scheduler.scheduleJob(jobDetail, trigger);
            scheduler.start();
        } catch (SchedulerException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
    }


    /**
     *
     * @param taskName  定时任务名称
     * @param taskGroupName  定时任务组名
     * @param triggerName  触发器名称
     * @param triggerGroupName  触发器组名
     * @param cls  定时任务 类 类型
     * @param cron 表达式
     * @param map 需要传递的参数
     * @return 0:任务已经存在，1：任务添加成功，2：操作异常
     */
    public  int addTask(String taskName, String taskGroupName, String triggerName, String triggerGroupName, Class cls, String cron, Map map) {
        try {
            if (bIsExists(triggerName, triggerGroupName)) {
                return 0;
            }
//            MyJobFactory myJobFactory = new MyJobFactory();
//            Scheduler scheduler = factory.getScheduler();
            JobDetail jobDetail = JobBuilder.newJob(cls).withIdentity(taskName, taskGroupName).build();
            jobDetail.getJobDataMap().putAll(map);
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cron);
            Trigger trigger = TriggerBuilder.newTrigger().withIdentity(triggerName, triggerGroupName).withSchedule(scheduleBuilder).build();
            scheduler.setJobFactory(myJobFactory);
            scheduler.scheduleJob(jobDetail, trigger);
            scheduler.start();
            return 1;
        } catch (SchedulerException e) {
            log.error("QuartzManage.addTask",e);
            return 2;
        }
    }

    /**
     * 倒计时任务
     * @param taskName
     * @param taskGroupName
     * @param triggerName
     * @param triggerGroupName
     * @param cls
     * @param seconds  多少秒以后执行
     * @param map
     * @return
     */
    public  int addTask(String taskName, String taskGroupName, String triggerName, String triggerGroupName, Class cls, int seconds, Map map){
        try {
            if (bIsExists(triggerName, triggerGroupName)) {
                return 0;
            }
//            Scheduler scheduler = factory.getScheduler();
            JobDetail jobDetail = JobBuilder.newJob(cls).withIdentity(taskName, taskGroupName).build();
            jobDetail.getJobDataMap().putAll(map);

            SimpleTriggerImpl simpleTrigger = new SimpleTriggerImpl();
            simpleTrigger.setKey(new TriggerKey(taskName));
            simpleTrigger.setName(triggerName);
            simpleTrigger.setGroup(triggerGroupName);
            simpleTrigger.setStartTime(new Date(new Date().getTime() + 1000 * seconds));
            simpleTrigger.setRepeatInterval(1000*seconds);
            simpleTrigger.setRepeatCount(0);
            scheduler.setJobFactory(myJobFactory);
            scheduler.scheduleJob(jobDetail, simpleTrigger);
            scheduler.start();
            return 1;
        } catch (SchedulerException e) {
            log.error("QuartzManage.addTask",e);
            return 2;
        }
    }





    public static boolean updateTask(String triggerName, String triggerGroupName, Class cls, String cron, Map map) {
        if (!bIsExists(triggerName, triggerGroupName)) {
            return false;
        }
        try {
            Scheduler scheduler = factory.getScheduler();
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cron);
            Trigger trigger = TriggerBuilder.newTrigger().withIdentity(triggerName, triggerGroupName).withSchedule(scheduleBuilder).build();
            trigger.getJobDataMap().clear();
            trigger.getJobDataMap().putAll(map);
            scheduler.rescheduleJob(TriggerKey.triggerKey(triggerName, triggerGroupName), trigger);
            return true;
        } catch (SchedulerException e) {
            e.printStackTrace();
            return false;
        }
    }


    public static boolean bIsExists(String triggerName, String triggerGroupName) {
        boolean isExists = true;
        try {
            Scheduler scheduler = factory.getScheduler();
            TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroupName);
            isExists = scheduler.checkExists(triggerKey);
        } catch (SchedulerException e) {
            e.printStackTrace();
        } finally {
            return isExists;
        }
    }

    public static Map getDataMap(String triggerName, String triggerGroupName) {
        try {
            Scheduler scheduler = factory.getScheduler();
            TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroupName);
            Trigger trigger = scheduler.getTrigger(triggerKey);
            return trigger.getJobDataMap();
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
        return new HashMap<>();
    }
}



