package com.template.common.utils;

import com.template.model.pojo.SmartDataSourceJobParams;
import com.template.model.pojo.SmartDataTask;
import org.quartz.*;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;

public class QuartzJobUtils {

    private static final String JobClass = "com.template.controller.Task";

    /**
     * 创建定时任务
     *
     * @param scheduler     调度器
     * @param smartDataTask_return 定时任务信息类
     */
    public static Map<String, Object> createScheduleJob(Scheduler scheduler, SmartDataTask smartDataTask_return) {
        // 判断是否存在该任务，存在则不创建任务，直接返回信息提示
        Map<String, Object> exists = exists(scheduler, smartDataTask_return.getTkName());
        if ("0".equals(exists.get("code"))) {
            return exists;
        }

        try {
            Class<? extends Job> jobClass = (Class<? extends Job>) Class.forName(JobClass);
            // 构建定时任务信息
            JobDetail jobDetail = JobBuilder.newJob(jobClass)
                    .withIdentity(smartDataTask_return.getTkName())
                    .build();

            // 创建一个JobDataMap对象，并设置参数
            JobDataMap jobDataMap = new JobDataMap();

            // 任务参数
            jobDataMap.put("smartDataTask", smartDataTask_return);

            // 将JobDataMap对象与JobDetail关联
            jobDetail.getJobDataMap().putAll(jobDataMap);

            // 设置定时任务的执行方式
            CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(smartDataTask_return.getTkCron());
            // 构建触发器
            CronTrigger cronTrigger = TriggerBuilder.newTrigger()
                    .withIdentity(smartDataTask_return.getTkName())
                    .withSchedule(cronScheduleBuilder)
                    .build();
            // 把触发器与任务进行绑定
            scheduler.scheduleJob(jobDetail, cronTrigger);

            return CommonUtil.getReturnMap(String.valueOf(0), "定时任务【" + smartDataTask_return.getTkName() + "】创建成功！");
        } catch (ClassNotFoundException e) {
            return CommonUtil.getReturnMap(String.valueOf(1), "找不到定时任务类!");
        } catch (SchedulerException e) {
            return CommonUtil.getReturnMap(String.valueOf(1), "创建定时任务出错：" + e.getMessage());
        }
    }

    public static String getNextExeTime(String cronExpression) {
        // 创建CronExpression对象
        CronExpression cron;
        try {
            cron = new CronExpression(cronExpression);
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }

        // 获取当前时间
        long currentTimeMillis = System.currentTimeMillis();

        // 计算下次执行时间
        Date nextValidTimeMillis = cron.getNextValidTimeAfter(new Date(currentTimeMillis));

        // 格式化输出
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return sdf.format(nextValidTimeMillis);
    }

    /**
     * 根据任务暂停定时任务
     *
     * @param scheduler 调度器
     * @param jobName   任务名称
     */
    public static Map<String, Object> pauseScheduleJob(Scheduler scheduler, String jobName) {
        Map<String, Object> exists = exists(scheduler, jobName);
        if ("1".equals(exists.get("code"))) {
            return exists;
        }

        JobKey jobKey = JobKey.jobKey(jobName);
        try {
            scheduler.pauseJob(jobKey);
            return CommonUtil.getReturnMap("0", "定时任务【" + jobName + "】暂停成功！");
        } catch (SchedulerException e) {
            return CommonUtil.getReturnMap("0", "定时任务【" + jobName + "】暂停出错：" + e.getMessage());
        }
    }

    private static Map<String, Object> exists(Scheduler scheduler, String jobName) {
        JobKey jobKey = new JobKey(jobName);
        try {
            if (scheduler.getJobDetail(jobKey) != null) {
                return CommonUtil.getReturnMap("0", "定时任务【" + jobName + "】已在运行！");
            } else {
                return CommonUtil.getReturnMap("1", "定时任务【" + jobName + "】不存在！");
            }
        } catch (SchedulerException e) {
            return CommonUtil.getReturnMap("1", "异常：" + e.getMessage());
        }
    }

    /**
     * 根据任务恢复定时任务
     *
     * @param scheduler 调度器
     * @param jobName   任务名称
     */
    public static Map<String, Object> resumeScheduleJob(Scheduler scheduler, String jobName) {
        Map<String, Object> exists = exists(scheduler, jobName);
        if ("1".equals(exists.get("code"))) {
            return exists;
        }

        JobKey jobKey = JobKey.jobKey(jobName);
        try {
            scheduler.resumeJob(jobKey);
            return CommonUtil.getReturnMap("0", "定时任务【" + jobName + "】已恢复成功！");
        } catch (SchedulerException e) {
            return CommonUtil.getReturnMap("1", "定时任务【" + jobName + "】恢复出错：" + e.getMessage());
        }
    }

    /**
     * 根据任务名称立即运行一次定时任务
     *
     * @param scheduler 调度器
     * @param jobName   任务名称
     */
    public static Map<String, Object> runOnce(Scheduler scheduler, String jobName) {
        Map<String, Object> exists = exists(scheduler, jobName);
        if ("1".equals(exists.get("code"))) {
            return exists;
        }

        JobKey jobKey = JobKey.jobKey(jobName);
        try {
            scheduler.triggerJob(jobKey);
            return CommonUtil.getReturnMap("0", "定时任务【" + jobName + "】立即运行1次成功！");
        } catch (SchedulerException e) {
            return CommonUtil.getReturnMap("1", "定时任务【" + jobName + "】立即运行1次出错：" + e.getMessage());
        }
    }

    /**
     * 根据任务更新定时任务
     *
     * @param scheduler     调度器
     * @param smartDataTask 定时任务信息类
     */
    public static Map<String, Object> updateScheduleJob(Scheduler scheduler, SmartDataTask smartDataTask) {
        Map<String, Object> exists = exists(scheduler, smartDataTask.getTkName());
        if ("1".equals(exists.get("code"))) {
            return exists;
        }

        try {
            //获取到对应任务的触发器
            TriggerKey triggerKey = TriggerKey.triggerKey(smartDataTask.getTkName());
            //设置定时任务的执行方式
            CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(smartDataTask.getTkCron());
            //重新构建任务的触发器
            CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
            trigger = trigger.getTriggerBuilder()
                    .withIdentity(triggerKey)
                    .withSchedule(cronScheduleBuilder)
                    .build();
            //重置对应的Job
            scheduler.rescheduleJob(triggerKey, trigger);
            return CommonUtil.getReturnMap("0", "定时任务【" + smartDataTask.getTkName() + "】刷新成功！");
        } catch (SchedulerException e) {
            return CommonUtil.getReturnMap("1", "定时任务【" + smartDataTask.getTkName() + "】刷新出错：" + e.getMessage());
        }
    }

    /**
     * 根据定时任务名称从调度器中除定时任务
     *
     * @param scheduler 调度器
     * @param jobName   任务名称
     */
    public static Map<String, Object> deleteScheduleJob(Scheduler scheduler, String jobName) {
        Map<String, Object> exists = exists(scheduler, jobName);
        if ("1".equals(exists.get("code"))) {
            return exists;
        }

        JobKey jobKey = JobKey.jobKey(jobName);
        try {
            scheduler.deleteJob(jobKey);
            return CommonUtil.getReturnMap(String.valueOf(0), "定时任务【" + jobName + "】停止成功！");
        } catch (SchedulerException e) {
            return CommonUtil.getReturnMap(String.valueOf(1), "定时任务【" + jobName + "】停止出错：" + e.getMessage());
        }
    }
}
