package com.leanwo.activiti.service.base.impl;

import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.gson.Gson;
import com.leanwo.activiti.dto.ProcessReportResultResponse;
import com.leanwo.activiti.dto.ProcessResult;
import com.leanwo.activiti.dto.base.TaskDefineDto;
import com.leanwo.activiti.dto.base.TaskInstanceStatus;
import com.leanwo.activiti.service.base.HttpTaskEngine;
import com.leanwo.activiti.service.base.ProcessReportEngine;
import com.leanwo.activiti.service.base.ProcessReportService;
import com.leanwo.activiti.service.base.QuartzEngine;
import com.leanwo.activiti.service.base.TokenService;
import com.leanwo.activiti.util.GsonUtil;
import com.leanwo.activiti.util.LoginContext;
import com.leanwo.activiti.util.LoginContextUtil;
import com.leanwo.activiti.util.SpringUtil;
import com.leanwo.activiti.util.StringUtil;
import com.leanwo.activiti.util.TokenUtil;

/**
 * 流程报表自动运行
 * 
 * @author YangZhiJie
 *
 */
public class ProcessReportAutoRun implements Job {

	private static Logger logger = LoggerFactory.getLogger(ProcessReportAutoRun.class);

	@Override
	public void execute(JobExecutionContext context) throws JobExecutionException {
		JobDetail detail = context.getJobDetail();
		JobDataMap map = detail.getJobDataMap();
		TaskDefineDto taskDefineDto = (TaskDefineDto) map.get(QuartzEngine.TaskDefineDto);

		Long accountId = map.getLong(QuartzEngine.AccountId);
		LoginContext loginContext = new LoginContext();
		loginContext.setAccountId(accountId);
		LoginContextUtil.setLoginContext(loginContext);

		TokenService tokenService = (TokenService) SpringUtil.getSingleBean(TokenService.class);
		String tempToken = tokenService.generateTempToken();
		TokenUtil.setToken(tempToken);

		if (!SpringUtil.initSuccess()) {
			logger.info("Spring 容器正在启动，无法运行流程。");
			return;
		}

		if (StringUtil.isEmpty(TokenUtil.getToken())) {
			logger.info("未获取到token。");
			return;
		}

		if (taskDefineDto == null) {
			logger.error("无配置，不能运行。");
			return;
		}

		logger.debug(taskDefineDto.toString() + "运行开始。");

		if (taskDefineDto.getClientId() == null) {
			logger.error(taskDefineDto.toString() + "无单位Id，不能运行。");
			return;
		}

		if (StringUtil.isEmpty(taskDefineDto.getProcessReportNo())) {
			logger.error(taskDefineDto.toString() + "无流程和报表Id，不能运行。");
			return;
		}

		ProcessReportEngine processReportEngine = (ProcessReportEngine) SpringUtil
				.getBean("processReportEngineImpl" + accountId);

		if (processReportEngine == null) {
			logger.error("获取bean:'processReportEngine'失败");
			return;
		}

		Long timeSerialNumber = System.currentTimeMillis();

		try {

            ProcessReportService processReportService = (ProcessReportService) SpringUtil
                    .getSingleBean(ProcessReportService.class);

			// 生成流程实例
			processReportEngine.addTaskInstance(timeSerialNumber, taskDefineDto);

			ProcessReportResultResponse processReportResultResponse = processReportService.autoRun(taskDefineDto);
			String operationResult = null;
			TaskInstanceStatus taskInstanceStatus = null;

			if (processReportResultResponse != null) {
				operationResult = GsonUtil.getGson().toJson(processReportResultResponse);
				ProcessResult processResult = processReportResultResponse.getProcessResult();
				if (processResult != null && processResult.getSuccess() != null && processResult.getSuccess()) {
					taskInstanceStatus = TaskInstanceStatus.SUCCESS;
				} else {
					taskInstanceStatus = TaskInstanceStatus.FAIL;
				}
			} else {
				operationResult = taskDefineDto.toString() + "未获取到流程报表执行结果。";
				taskInstanceStatus = TaskInstanceStatus.FAIL;
			}
			// 更新流程实例
			processReportEngine.updateTaskInstance(timeSerialNumber, operationResult, taskInstanceStatus,
					taskDefineDto);
		} catch (Throwable e) {
			// 更新流程实例
			processReportEngine.updateTaskInstance(timeSerialNumber, "运行失败," + e.getMessage(), TaskInstanceStatus.FAIL,
					taskDefineDto);
		} finally {
			logger.debug(taskDefineDto.toString() + "运行完毕。");
		}
	}
}
