package com.wms_main.quartz;

import com.wms_main.constant.enums.jobs.JobTimerTypeEnums;
import com.wms_main.quartz.config.JobBean;
import lombok.RequiredArgsConstructor;
import org.quartz.*;

import java.util.Objects;

/**
 * 定时任务工具类
 */
@RequiredArgsConstructor
public class JobUtils {

    /**
     * 创建任务
     * @param scheduler 调度器
     * @param jobBean 任务信息
     */
    public static void createJob(Scheduler scheduler, JobBean jobBean) {
        try {
            // 生成任务
            JobDetail jobDetail = JobBuilder.newJob(jobBean.getJobClass())
                    .storeDurably()
                    .withIdentity(jobBean.getJobName())
                    .build();
            // 生成触发器
            TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger()
                    .forJob(jobDetail)
                    .withIdentity(jobBean.getJobName() + "_trigger");
            if (Objects.equals(jobBean.getTimerType(), JobTimerTypeEnums.CRON.getType())) {
                // cron
                triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(jobBean.getCronExpression()));
            } else {
                // 简单定时器
                if (jobBean.getTimer() == null || jobBean.getTimer() < 100) {
                    triggerBuilder.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInMilliseconds(100).repeatForever());
                } else {
                    triggerBuilder.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInMilliseconds(jobBean.getTimer()).repeatForever());
                }
            }
            Trigger trigger = triggerBuilder.build();
            scheduler.scheduleJob(jobDetail, trigger);
        } catch (SchedulerException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 暂停定时任务
     * @param scheduler 调度器
     * @param jobName 任务名
     */
    public static void pauseJob(Scheduler scheduler, String jobName) {
        try {
            scheduler.pauseJob(JobKey.jobKey(jobName));
        } catch (SchedulerException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 恢复定时任务
     * @param scheduler 调度器
     * @param jobName 任务名
     */
    public static void resumeJob(Scheduler scheduler, String jobName) {
        try {
            scheduler.resumeJob(JobKey.jobKey(jobName));
        } catch (SchedulerException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 删除定时任务
     * @param scheduler 调度器
     * @param jobName 任务名
     */
    public static void deleteJob(Scheduler scheduler, String jobName) {
        try {
            scheduler.deleteJob(JobKey.jobKey(jobName));
        } catch (SchedulerException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 立即执行一次任务
     * @param scheduler 调度器
     * @param jobName 任务名
     */
    public static void runJobOnce(Scheduler scheduler, String jobName) {
        try {
            scheduler.triggerJob(JobKey.jobKey(jobName));
        } catch (SchedulerException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 更新任务信息
     * @param scheduler 调度器
     * @param jobBean 任务信息
     */
    public static void modifyJob(Scheduler scheduler, JobBean jobBean) {
        try {
            // 获取触发器唯一标识
            TriggerKey triggerKey = TriggerKey.triggerKey(jobBean.getJobName() + "_trigger");
            if (Objects.equals(jobBean.getTimerType(), JobTimerTypeEnums.CRON.getType())) {// cron
                // 获取触发器唯一对象
                CronTrigger oldTrigger = (CronTrigger) scheduler.getTrigger(triggerKey);
                // 使用新cron表达式构建新的触发器
                CronTrigger newTrigger = oldTrigger.getTriggerBuilder()
                        .withSchedule(CronScheduleBuilder.cronSchedule(jobBean.getCronExpression()))
                        .build();
                // 调度器更新最新的触发器
                scheduler.rescheduleJob(triggerKey, newTrigger);
            } else {
                // 获取触发器唯一对象
                SimpleTrigger oldTrigger = (SimpleTrigger) scheduler.getTrigger(triggerKey);
                // 使用新cron表达式构建新的触发器
                SimpleTrigger newTrigger;
                if (jobBean.getTimer() == null || jobBean.getTimer() < 100) {
                    newTrigger = oldTrigger.getTriggerBuilder()
                            .withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInMilliseconds(100).repeatForever())
                            .build();
                } else {
                    newTrigger = oldTrigger.getTriggerBuilder()
                            .withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInMilliseconds(jobBean.getTimer()).repeatForever())
                            .build();
                }
                // 调度器更新最新的触发器
                scheduler.rescheduleJob(triggerKey, newTrigger);
            }
        } catch (SchedulerException e) {
            throw new RuntimeException(e);
        }
    }
}
