package com.cku.oa.sys.service;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.impl.StdScheduler;
import org.quartz.impl.StdSchedulerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.cku.oa.sys.dao.TaskTriggerDao;
import com.cku.oa.sys.entity.TaskLog;
import com.cku.oa.sys.entity.TaskTrigger;
import com.thinkgem.jeesite.common.persistence.Page;
import com.thinkgem.jeesite.common.service.CrudService;
import com.thinkgem.jeesite.common.utils.IdGen;
import com.thinkgem.jeesite.modules.sys.entity.User;

/**
 * 计划任务管理Service
 * @author zhuoHeng
 * @version 2017-03-29
 */
@Service
@Transactional(readOnly = true)
public class TaskTriggerService extends CrudService<TaskTriggerDao, TaskTrigger> {
	
	@Autowired
	private TaskTriggerDao sysTaskDao;
	
	@Autowired
	private TaskLogService taskLogService;
	
	private static String JOB_GROUP_NAME = "EXTJWEB_JOBGROUP_NAME";
	
	public TaskTrigger get(String id) {
		return super.get(id);
	}
	
	public List<TaskTrigger> findList(TaskTrigger sysTask) {
		return super.findList(sysTask);
	}
	
	public Page<TaskTrigger> findPage(Page<TaskTrigger> page, TaskTrigger sysTask) {
		return super.findPage(page, sysTask);
	}
	
	/**
	 * 
	 * @Description：因执行状态需从job中读取，对数据集合进行重组
	 * @author: zhuoHeng
	 * @version: 2017年4月14日 下午3:08:08
	 */
	public Page<TaskTrigger> recombinePage(Page<TaskTrigger> page, TaskTrigger sysTask) throws SchedulerException {
		List<TaskTrigger> list = dao.findList(sysTask);
		SchedulerFactory factory = new StdSchedulerFactory();
		Scheduler scheduler = factory.getScheduler();
		JobDetail jobDetail = null;
		for (int i = 0; i < list.size(); i++) {
			jobDetail = scheduler.getJobDetail(JobKey.jobKey(list.get(i).getJobName(), list.get(i).getJobGroup()));
			if(jobDetail!=null){
				list.get(i).setState("1");
			} else {
				list.get(i).setState("0");
			}
		}
		List<TaskTrigger> newList = new ArrayList<>();
		if("1".equals(sysTask.getState())){
			for (int i = 0; i < list.size(); i++) {
				jobDetail = scheduler.getJobDetail(JobKey.jobKey(list.get(i).getJobName(), list.get(i).getJobGroup()));
				if(jobDetail!=null){
					list.get(i).setState("1");
					newList.add(list.get(i));
				}
			}
		} else if("0".equals(sysTask.getState())){
			for (int i = 0; i < list.size(); i++) {
				jobDetail = scheduler.getJobDetail(JobKey.jobKey(list.get(i).getJobName(), list.get(i).getJobGroup()));
				if(jobDetail==null){
					list.get(i).setState("0");
					newList.add(list.get(i));
				}
			}
		} else {
			newList = list;
		}
		page.setList(newList);
		sysTask.setPage(page);
		page.setCount(newList.size());
		return page;
	}
	
	
	@Transactional(readOnly = false)
	public void save(TaskTrigger sysTask) {
		// 解决定时任务，首次创建不执行的问题
		if (sysTask.getIsNewRecord()){
			sysTask.setExecuteState("0");
		}
		super.save(sysTask);
	}
	
	@Transactional(readOnly = false)
	public void delete(TaskTrigger sysTask) {
		super.delete(sysTask);
	}

	/**
	 * 
	 * @Description：更改计划任务运行状态
	 * @author: zhuoHeng
	 * @version: 2017年3月29日 上午10:54:16
	 * @throws ClassNotFoundException 
	 */
	@Transactional(readOnly = false)
	public void changeState(TaskTrigger sysTask) throws ClassNotFoundException {
		
		try {
			SchedulerFactory factory = new StdSchedulerFactory();
			StdScheduler scheduler = (StdScheduler) factory.getScheduler();
			
			JobDetail jobDetail = scheduler.getJobDetail(JobKey.jobKey(sysTask.getJobName(), sysTask.getJobGroup()));
			if(jobDetail == null){
				ChangeTimeService.addJob(scheduler, sysTask.getJobName(), sysTask.getJobGroup(), sysTask.getJobName(), 
						"EXTJWEB_TRIGGERGROUP_NAME", Class.forName(sysTask.getJobCls()), sysTask.getTimeFormat(),sysTask.getJobInfo());
				sysTask.setState("1");
			} else {
				ChangeTimeService.removeJob(scheduler, sysTask.getJobName());
				sysTask.setState("0");
			}
			sysTaskDao.changeState(sysTask);
		} catch (SchedulerException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 
	 * @Description：开启所有定时任务
	 * @author: zhuoHeng
	 * @version: 2017年4月6日 下午2:51:03
	 */
	@Transactional(readOnly = false)
	public void startAll() throws ClassNotFoundException {
		try {
			List<TaskTrigger> list = dao.findAll();
			StdSchedulerFactory factory = new StdSchedulerFactory();
			StdScheduler scheduler = (StdScheduler) factory.getScheduler();
			JobDetail jobDetail = null;
			for (TaskTrigger sysTask: list) {
				jobDetail = scheduler.getJobDetail(JobKey.jobKey(sysTask.getJobName(), sysTask.getJobGroup()));
				if(jobDetail == null){
					ChangeTimeService.addJob(scheduler, sysTask.getJobName(), sysTask.getJobGroup(), sysTask.getJobName(), 
							"EXTJWEB_TRIGGERGROUP_NAME", Class.forName(sysTask.getJobCls()), sysTask.getTimeFormat(),sysTask.getJobInfo());
				}
			}
		} catch (SchedulerException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 
	 * @Description：停止所有计划任务
	 * @author: zhuoHeng
	 * @version: 2017年4月6日 下午2:50:38
	 */
	public void shutdownAll() throws ClassNotFoundException {
		try {
			List<TaskTrigger> list = dao.findAll();
			StdSchedulerFactory factory = new StdSchedulerFactory();
			StdScheduler scheduler = (StdScheduler) factory.getScheduler();
			JobDetail jobDetail = null;
			for (TaskTrigger sysTask: list) {
				jobDetail = scheduler.getJobDetail(JobKey.jobKey(sysTask.getJobName(), sysTask.getJobGroup()));
				if(jobDetail != null){
					ChangeTimeService.removeJob(scheduler, sysTask.getJobName());
				}
			}
		} catch (SchedulerException e) {
			e.printStackTrace();
		}
	}
	/**
	 * 
	 * @Description：立即执行一次方法
	 * @author: zhuoHeng
	 * @version: 2017年4月6日 上午10:26:52
	 */
	@Transactional(readOnly = false)
	public void executeOnce(TaskTrigger sysTask) {
		try {
			int count = 0;
			Class<?> clazz = Class.forName(sysTask.getJobCls());
			Method method = clazz.getMethod("executeOnce");
			Object objct = method.invoke(clazz.newInstance());
			if(objct!=null){
				count = Integer.valueOf(objct.toString());
			}
			TaskLog taskLog = new TaskLog();
			Date date = new Date();
			taskLog.setId(IdGen.uuid());
			taskLog.setIsNewRecord(true);
			taskLog.preInsert();
			taskLog.setJobInfo(sysTask.getJobInfo());
			taskLog.setJobName(sysTask.getJobName());
			taskLog.setJobGroup("无");
			taskLog.setExecuteType("1");
			taskLog.setExecuteTime(date);
			taskLog.setSuccessCount(String.valueOf(count==-1?0:count));
			taskLog.setSuccessState(String.valueOf(count==-1?1:0));
			taskLog.setCreateDate(date);
			taskLog.setUpdateDate(date);
			taskLog.setDelFlag("0");
			taskLog.setCreateBy(new User());
			taskLog.setUpdateBy(new User());
			taskLogService.addLog(taskLog);
			
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 
	 * @Description：计划任务执行完成后更新执行时间
	 * @author: zhuoHeng
	 * @version: 2017年4月10日 下午2:02:15
	 */
	@Transactional(readOnly = false)
	public void renewExecuteTime(String jobName,Date date){
		dao.renewExecuteTime(jobName,date);
	}

	/**
	 * 
	 * @Description：根据jobName查询最后一次执行时间
	 * @author: zhuoHeng
	 * @version: 2017年4月13日 下午2:24:20
	 */
	public void validateExecute(String name) {
		
	}
	
	@Transactional(readOnly = false)
	public int renewExecuteState(String executeState,String jobName){
		return dao.renewExecuteState(executeState, jobName);
	}
	
	public TaskTrigger getExecuteState(String jobName){
		return dao.getExecuteState(jobName);
	}

}