package com.cftech.accounts.service;


import com.cftech.accounts.model.SysJob;
import com.cftech.core.util.StringUtils;
import lombok.extern.java.Log;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.quartz.*;
import org.quartz.impl.matchers.GroupMatcher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author KangLiang Huang
 * <p>
 * 定时任务类 增删改 可参考api：http://www.quartz-scheduler.org/api/2.2.1/
 * <p>
 * 任务名称 默认为 SysJob 类 id
 */
@Service
@Slf4j
public class JobTask {

    @Autowired
    SchedulerFactoryBean schedulerFactoryBean;


    /**
     *  查看目前内存中的Job 信息
     */
//    public List<String> getRAMJobs()
//    {
//        List<String> infos = new ArrayList<String>();
//        Scheduler scheduler = schedulerFactoryBean.getScheduler();
//        try {
//            List<JobExecutionContext> jobsContexts = scheduler.getCurrentlyExecutingJobs();
//            for(JobExecutionContext jobsContext:jobsContexts)
//            {
//                JobDetail jobDetail = jobsContext.getJobDetail();
//                infos.add(jobDetail.getJobDataMap().get("uid").toString());
//            }
//        } catch (SchedulerException e) {
//            e.printStackTrace();
//        }
//        return infos;
//    }


    public Set<String> getRAMJOBS()
    {
        Set<String> infos = new HashSet<String>();
        Scheduler scheduler = schedulerFactoryBean.getScheduler();
        try {
            for (String groupName : scheduler.getJobGroupNames()) {
                for (JobKey jobKey : scheduler.getJobKeys(GroupMatcher.jobGroupEquals(groupName))) {
                    String jobName = jobKey.getName();
                    String jobGroup = jobKey.getGroup();
                    //get job's trigger
                    List<Trigger> triggers = (List<Trigger>) scheduler.getTriggersOfJob(jobKey);
                    for(Trigger tt:triggers)
                    {
                        infos.add(tt.getKey().getName());
                    }
//                    Date nextFireTime = triggers.get(0).getNextFireTime();
//                    System.out.println("[jobName] : " + jobName + " [groupName] : "
//                            + jobGroup + " - " + nextFireTime);

                }
            }
        }catch (SchedulerException e) {
                e.printStackTrace();
            }
        return infos;
    }



    /**
     * true 存在 false 不存在
     *
     * @param
     * @return
     */
    public boolean checkJob(SysJob job) {
        Scheduler scheduler = schedulerFactoryBean.getScheduler();
        TriggerKey triggerKey = TriggerKey.triggerKey(job.getJobuid(), Scheduler.DEFAULT_GROUP);
        try {
            if (scheduler.checkExists(triggerKey)) {
                return true;
            }
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 开启
     */
    public boolean startJob(SysJob job) {
        Scheduler scheduler = schedulerFactoryBean.getScheduler();
        try {
            Class clazz = Class.forName(job.getClazzPath());
            JobDetail jobDetail = JobBuilder.newJob(clazz).usingJobData("uid",job.getJobuid()).usingJobData("type",job.getType()).build();

            // 触发器
            TriggerKey triggerKey = TriggerKey.triggerKey(job.getJobuid(), Scheduler.DEFAULT_GROUP);
            //修改出发器，只执行一次任务
            Trigger trigger = null;
            if(StringUtils.isNotBlank(job.getCron()))
            {
                    trigger = TriggerBuilder.newTrigger()
                    .withIdentity(triggerKey)
                    .withSchedule(CronScheduleBuilder.cronSchedule(job.getCron())).build();
            }else if(StringUtils.isNotBlank(job.getJobDesc()))
            {
                //获得时间
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                Date startDate = sdf.parse(job.getJobDesc()+":00");
                  trigger = TriggerBuilder.newTrigger().withIdentity(triggerKey)
                        .startAt(startDate).withSchedule(SimpleScheduleBuilder.simpleSchedule().withRepeatCount(0)).build();
            }
            scheduler.scheduleJob(jobDetail, trigger);
            // 启动
            if (scheduler.isShutdown()) {
                scheduler.start();
                log.info("---任务[" + triggerKey.getName() + "]启动成功-------");
            } else {
                log.info("---任务[" + triggerKey.getName() + "]已经调度运行成功，请勿再次启动主线程-------");
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return true;
    }

    /**
     * 更新
     */
    public boolean updateJob(SysJob job) {
        Scheduler scheduler = schedulerFactoryBean.getScheduler();
        String createTime = DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss");

        TriggerKey triggerKey = TriggerKey.triggerKey(job.getJobuid(), Scheduler.DEFAULT_GROUP);
        try {
            if (scheduler.checkExists(triggerKey)) {
                return false;
            }

            JobKey jobKey = JobKey.jobKey(job.getJobuid(), Scheduler.DEFAULT_GROUP);

            CronScheduleBuilder schedBuilder = CronScheduleBuilder.cronSchedule(job.getCron())
                    .withMisfireHandlingInstructionDoNothing();
            CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(triggerKey)
                    .withDescription(createTime).withSchedule(schedBuilder).build();
            Class clazz = null;
            JobDetail jobDetail = scheduler.getJobDetail(jobKey);
            HashSet<Trigger> triggerSet = new HashSet<>();
            triggerSet.add(trigger);
            scheduler.scheduleJob(jobDetail, triggerSet, true);
            log.info("---任务[" + triggerKey.getName() + "]更新成功-------");
            return true;
        } catch (SchedulerException e) {
            e.printStackTrace();
            throw new RuntimeException(e.getMessage());
        }
    }

    /**
     * 删除
     */
    public boolean remove(SysJob job) {
        Scheduler scheduler = schedulerFactoryBean.getScheduler();
        TriggerKey triggerKey = TriggerKey.triggerKey(job.getJobuid(), Scheduler.DEFAULT_GROUP);
        try {
            if (checkJob(job)) {
                scheduler.pauseTrigger(triggerKey);
                scheduler.unscheduleJob(triggerKey);
                scheduler.deleteJob(JobKey.jobKey(job.getJobuid(), Scheduler.DEFAULT_GROUP));
                log.info("---任务[" + triggerKey.getName() + "]删除成功-------");
                return true;
            }
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
        return false;
    }
}
