/**
 * 
 */
package com.huatek.busi.service.impl.job;

import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobBuilder;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSON;
import com.huatek.busi.common.ScheduleStatus;
import com.huatek.busi.entity.ScheduleJob;

/**
  * @ClassName: ScheduleManager
  * @FullClassPath: com.huatek.busi.service.impl.job.ScheduleManager
  * @Description: TODO
  * @author: Arno
  * @date: Jul 3, 2019 2:48:28 PM
  * @version: 1.0
  */

public class ScheduleManager {

	 protected final static Logger logger = LoggerFactory.getLogger(ScheduleManager.class);
	 
	 
    private final static String JOB_NAME = "TASK_";
    
   
 
	
    /** 
    * @Title: getCronTrigger 
    * @Description: 获取表达式触发器 
    * @createDate: Jul 3, 2019 3:02:49 PM
    * @param    jobId 任务id
    * @return   CronTrigger    
    * @throws 
    */ 
    public static CronTrigger getCronTrigger(Scheduler scheduler, String jobId) {
        try {
            return (CronTrigger) scheduler.getTrigger(getTriggerKey(jobId));
        } catch (SchedulerException e) {
           // throw new BusinessException("获取定时任务CronTrigger出现异常", e);
        	logger.error("获取定时任务CronTrigger异常 --- > {}", e.getMessage());
        }
        return null ;
    }
    

    
    /** 
    * @Title: createScheduleJob 
    * @Description: 创建定时任务 
    * @createDate: Jul 3, 2019 3:02:22 PM
    * @param    scheduleJob   任务对象
    * @return   void    
    * @throws 
    */ 
    public static void createScheduleJob(Scheduler scheduler, ScheduleJob scheduleJob) {
        try {
        	//构建job信息
            JobDetail jobDetail = JobBuilder.newJob(CustomJobBean.class).withIdentity(getJobKey(scheduleJob.getId())).build();

            //表达式调度构建器
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression())
            		.withMisfireHandlingInstructionDoNothing();

            //按新的cronExpression表达式构建一个新的trigger
            CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(getTriggerKey(scheduleJob.getId())).withSchedule(scheduleBuilder).build();

            //放入参数，运行时的方法可以获取
            jobDetail.getJobDataMap().put(JobConstant.JOB_PARAM_KEY, JSON.toJSONString(scheduleJob));
            
            scheduler.scheduleJob(jobDetail, trigger);
            
            //暂停任务
            if(scheduleJob.getStatus() == ScheduleStatus.PAUSE.getValue()){
            	pauseJob(scheduler, scheduleJob.getId());
            }
        } catch (SchedulerException e) {
           // throw new BusinessException("创建定时任务失败", e);
        	logger.error("创建定时任务失败 --- > {}", e.getMessage());
        }
    }
    
  
    /** 
    * @Title: updateScheduleJob 
    * @Description: 更新定时任务 
    * @createDate: Jul 3, 2019 3:02:06 PM
    * @param    scheduleJob   任务对象
    * @return   void    
    * @throws 
    */ 
    public static void updateScheduleJob(Scheduler scheduler, ScheduleJob scheduleJob) {
        try {
            TriggerKey triggerKey = getTriggerKey(scheduleJob.getId());

            //表达式调度构建器
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression())
            		.withMisfireHandlingInstructionDoNothing();

            CronTrigger trigger = getCronTrigger(scheduler, scheduleJob.getId());
            
            //按新的cronExpression表达式重新构建trigger
            trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
            
            //参数
            trigger.getJobDataMap().put(JobConstant.JOB_PARAM_KEY, JSON.toJSONString(scheduleJob));
            
            scheduler.rescheduleJob(triggerKey, trigger);
            
            //暂停任务
            if(scheduleJob.getStatus() == ScheduleStatus.PAUSE.getValue()){
            	pauseJob(scheduler, scheduleJob.getId());
            }
            
        } catch (SchedulerException e) {
            //throw new BusinessException("更新定时任务失败", e);
        	logger.error("更新定时任务失败 --- > {}", e.getMessage());
        }
    }
    
    
    
    /** 
    * @Title: run 
    * @Description: 立即执行任务 
    * @createDate: Jul 3, 2019 3:01:37 PM
    * @param    scheduleJob 任务对象
    * @return   void    
    * @throws 
    */ 
    public static void run(Scheduler scheduler, ScheduleJob scheduleJob) {
        try {
        	//参数
        	JobDataMap dataMap = new JobDataMap();
        	dataMap.put(JobConstant.JOB_PARAM_KEY, JSON.toJSONString(scheduleJob));
        	
            scheduler.triggerJob(getJobKey(scheduleJob.getId()), dataMap);
        } catch (SchedulerException e) {
           // throw new BusinessException("立即执行定时任务失败", e);
        	logger.error("立即执行定时任务失败 --- > {}", e.getMessage());
        }
    }

  
    /** 
    * @Title: pauseJob 
    * @Description: 暂停任务 
    * @createDate: Jul 3, 2019 3:01:11 PM
    * @param    jobId 任务id
    * @return   void    
    * @throws 
    */ 
    public static void pauseJob(Scheduler scheduler, String jobId) {
        try {
            scheduler.pauseJob(getJobKey(jobId));
        } catch (SchedulerException e) {
           // throw new BusinessException("暂停定时任务失败", e);
        	logger.error("暂停定时任务失败 --- > {}", e.getMessage());
        }
    }

   
    /** 
    * @Title: resumeJob 
    * @Description: 恢复任务 
    * @createDate: Jul 3, 2019 3:01:00 PM
    * @param    jobId 任务id
    * @return   void    
    * @throws 
    */ 
    public static void resumeJob(Scheduler scheduler, String jobId) {
        try {
            scheduler.resumeJob(getJobKey(jobId));
        } catch (SchedulerException e) {
            //throw new BusinessException("暂停定时任务失败", e);
        	logger.error("恢复任务失败 --- > {}", e.getMessage());
        }
    }

    
    /** 
    * @Title: deleteScheduleJob 
    * @Description: 删除定时任务 
    * @createDate: Jul 3, 2019 2:59:26 PM
    * @param    jobId 任务id
    * @return   void    
    * @throws 
    */ 
    public static void deleteScheduleJob(Scheduler scheduler, String jobId) {
        try {
            scheduler.deleteJob(getJobKey(jobId));
        } catch (SchedulerException e) {
           // throw new BusinessException("删除定时任务失败", e);
            logger.error("删除任务失败 --- > {}", e.getMessage());
        }
    }
    
    /** 
     * @Title: getTriggerKey 
     * @Description:  获取触发器key 
     * @createDate: Jul 3, 2019 3:03:22 PM
     * @param    jobId 任务id
     * @return   TriggerKey    
     * @throws 
     */ 
     public static TriggerKey getTriggerKey(String jobId) {
         return TriggerKey.triggerKey(JOB_NAME + jobId);
     }
     
    
     /** 
     * @Title: getJobKey 
     * @Description: 获取jobKey 
     * @createDate: Jul 3, 2019 3:03:06 PM
     * @param     jobId 任务id
     * @return   JobKey    
     * @throws 
     */ 
     public static JobKey getJobKey(String jobId) {
         return JobKey.jobKey(JOB_NAME + jobId);
     }
     
}
