package com.blueland.bpm.engine.core.executor;

import java.util.HashMap;
import java.util.Map;

import org.activiti.engine.impl.interceptor.Command;
import org.activiti.engine.impl.persistence.entity.ExecutionEntity;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.springframework.stereotype.Service;

import com.blueland.bpm.common.util.StringUtils;
import com.blueland.bpm.engine.core.cmd.TempSaveTaskCmd;
import com.blueland.bpm.engine.core.model.ProcessInputModel;
import com.blueland.bpm.engine.core.model.ProcessInstanceModel;
import com.blueland.bpm.engine.util.PageFieldsUtil;
import com.blueland.bpm.engine.util.WorkFlowContants;
import com.blueland.bpm.engine.util.WorkFlowException;
/**
 * 流程贯穿-服务任务异步执行类
 * @version:  1.0
 * @author lw 
 */
@Service(WorkFlowContants.ACTION_TYPE_THROUGH_PROCESS)
public class ThroughProcessExecutor  extends AbstractProcessExecutor  implements ProcessExecutor{

	@Override
	public ProcessInstanceModel execute(ProcessInputModel processInputModel)
			throws WorkFlowException {
		Map<String, Object> workflowMap = new HashMap<String, Object>();
		
		ProcessDefinition processDefinition = this.repositoryService
				.getProcessDefinition(processInputModel.getWf_procDefId());
		additionalProcessInputModel(processInputModel, processDefinition);

		// 设置参数到引擎变量中
		workflowMap.put(WorkFlowContants.WF_PROCESS_INPUT_VARIABLE_KEY,
				processInputModel);
		workflowMap.putAll(processInputModel.getWf_variables());
		String receiver = processInputModel.getWf_receiver();
		// 设置流程发起人
		identityService
				.setAuthenticatedUserId(receiver);
		// ----------------------------------
		ProcessInstanceModel processInstanceModel = new ProcessInstanceModel();
		ProcessInstance processInstance = null;
		// 新建暂存
		if (StringUtils.isEmpty(processInputModel.getWf_curActInstId())
				|| StringUtils.isEmpty(processInputModel.getWf_procInstId())) {
			processInputModel
					.setWf_actionType(WorkFlowContants.ACTION_TYPE_LAUCH_SAVE_PROCESS);
			identityService.setAuthenticatedUserId(receiver);
			// 启动流程
			processInstance = this.runtimeService.startProcessInstanceById(
					processInputModel.getWf_procDefId(),
					processInputModel.getWf_businessKey(), workflowMap);
			
		} else {// 待办暂存
			// 查询流程
			processInstance =  getProcessInstance(processInputModel.getWf_procInstId());
		}
		// 在服务任务中调用流程贯穿功能时,流程都在同一个事物中，无法立即启动流程并返回
		// 根据sender获取起草环节的任务
		Task task = this.taskService.createTaskQuery()
				.processInstanceId(processInstance.getId())
				.taskAssignee(receiver).singleResult();
		if(task==null){
			ExecutionEntity executionEntity=(ExecutionEntity)processInstance;
			task=executionEntity.getTasks().get(0);
		}
		processInputModel.setWf_curActInstId(task.getId());
		// 下一步环节为空时,根据规则自动查询出下一步环节
		

		processInstanceModel = processInstanceModellBuilder.builderProcessInfo(
				processInputModel, processDefinition, processInstance, task);
		processInputModel.setWf_fields(PageFieldsUtil
				.fieldsToXml(processInputModel.getFields()));
		workflowMap.put(WorkFlowContants.WF_FIELDS_KEY,processInputModel.getWf_fields());
		workflowMap.put(WorkFlowContants.WF_CUR_COMMENT_KEY,
				processInputModel.getWf_curComment());

		Command<Void> tempSaveTaskCmd = new TempSaveTaskCmd(
				processInputModel.getWf_curActInstId(), workflowMap);
		this.managementService.executeCommand(tempSaveTaskCmd);
		return processInstanceModel;
	}
	
}
