package cn.hmsoft.frame.timer;

import java.time.LocalDateTime;
import java.util.Date;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

import cn.hmsoft.application.SpringHelper;
import cn.hmsoft.frame.constants.FrameStatus;
import cn.hmsoft.frame.data.dao.FrameTimerDao;
import cn.hmsoft.frame.data.model.FrameTimer;
import cn.hmsoft.frame.data.model.FrameTimerLog;
import cn.hmsoft.helper.LocalDateHelper;
import cn.hmsoft.log.LogHelper;

/*************************
 * 系统定时器基类，所有定时器必须继承此类才能正常被系统初始化
 * 
 * @author zxq
 * @create 2018-05-10 16:59:23
 * @version 5.0.0
 * @email: revisit@126.com
 * @Company: www.hmsoft.cn
 */
public abstract class FrameTimerConfig implements Job {

	protected FrameTimer timer;
	protected FrameTimerLog log;
	protected FrameTimerDao daoTimer;

	/*********************
	 * 单独运行
	 */
	public void execute(FrameTimer timer) {
		new Thread(new Runnable() {
			@Override
			public void run() {
				execute(timer, null);
			}
		}).start();
	}

	private void execute(FrameTimer timer, JobExecutionContext jobContext) {
		daoTimer = SpringHelper.getBean(FrameTimerDao.class);
		if (FrameStatus.Active.toString().equals(timer.getReload_param_flag()) && daoTimer != null) {
			// 重新加载参数
			try {
				FrameTimer t = daoTimer.find(FrameTimer.class, timer.getTimer_id());
				t.prepareParamMap();
				this.timer = t;
			} catch (Exception e) {

			}
		}

		this.start();
		try {
			this.execute();
		} catch (Exception e) {
			if (this.log != null)
				this.log.setLog_note(
						e.getMessage() + (this.log.getLog_note() == null ? "" : "|" + this.log.getLog_note()));
			LogHelper.error(e);
		}
		if (jobContext != null) {
			Date date = jobContext.getNextFireTime();
			if (date != null)
				timer.setTimer_next_time(LocalDateHelper.toLocalDateTime(date));
		}
		this.end();
	}

	@Override
	public void execute(JobExecutionContext jobContext) throws JobExecutionException {

		timer = (FrameTimer) jobContext.getJobDetail().getJobDataMap().get(FrameTimerUtil.TimerJobParamName);
		this.execute(timer, jobContext);

	}

	/*******************
	 * 实际执行
	 */
	protected abstract boolean execute() throws Exception;

	/*********************
	 * 定时运行
	 */
	protected void start() {
		if (daoTimer != null) {
			// 如果数据可用
			if (timer.getLog_flag().equals(FrameStatus.Active.toString())) {
				log = new FrameTimerLog();
				log.setTimer_id(timer.getTimer_id());
				log.setRun_start_time(LocalDateTime.now());
				log.setLog_param(timer.getTimer_param());
				this.daoTimer.insert(log);
			}

			this.daoTimer.updateRunningStatus(this.timer.getTimer_id(), FrameStatus.Active);
		}
	}

	/*********************
	 * 本地运行结束
	 */
	protected void end() {
		if (daoTimer != null) {
			// 如果数据可用
			if (this.log != null) {
				log.setRun_end_time(LocalDateTime.now());
				this.daoTimer.update(log);
			}

			this.daoTimer.updateRunningStatus(this.timer.getTimer_id(), FrameStatus.Active);
		}
	}

}
