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

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

import org.activiti.engine.impl.persistence.entity.ExecutionEntity;
import org.activiti.engine.impl.persistence.entity.HistoricTaskInstanceEntity;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.springframework.stereotype.Service;

import com.blueland.bpm.common.util.StringUtils;
import com.blueland.bpm.engine.core.model.ExceptionErrorCode;
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_SIGNAL_RECEIVE_ACTIVITY)
public class SignalReceiveActivityExecutor  extends AbstractProcessExecutor  implements ProcessExecutor{
	@Override
	public ProcessInstanceModel execute(ProcessInputModel processInputModel)
			throws WorkFlowException {
		if (processInputModel == null) {
			throw new WorkFlowException(ExceptionErrorCode.B2001,"流程输入参数对象{processInputModel}不能为空");
		}
		if (StringUtils.isEmpty(processInputModel.getWf_procInstId())) {
			throw new WorkFlowException(ExceptionErrorCode.B2001,String.format(
					"流程输入参数{流程实例ID:wf_procInstId}不能为空,processInputModel[%s]",
					processInputModel));
		} else if (StringUtils.isEmpty(processInputModel.getWf_curActDefId())) {
			throw new WorkFlowException(ExceptionErrorCode.B2001,String.format(
					"流程输入参数{信号环节ID:wf_curActDefId()}不能为空,processInputModel[%s]",
					processInputModel));
		} else if (StringUtils.isEmpty(processInputModel.getWf_procTitle())) {
			throw new WorkFlowException(ExceptionErrorCode.B2001,String.format(
					"流程输入参数{流程标题:wf_procTitle}不能为空,processInputModel[%s]",
					processInputModel));
		} 
		
		ProcessInstance processInstance =getProcessInstance(processInputModel.getWf_procInstId());
		ProcessDefinition processDefinition = getProcessDefinition(processInstance.getProcessDefinitionId());
		//validateProcessInputModel(processInputModel);
		Map<String, Object> workflowMap = new HashMap<String, Object>();
		// 设置参数到引擎变量中
		workflowMap.put(WorkFlowContants.WF_PROCESS_INPUT_VARIABLE_KEY,
				processInputModel);
		identityService
				.setAuthenticatedUserId(processInputModel.getWf_sender());
		// ----------------------------------
		ProcessInstanceModel processInstanceModel = null;
		try {
			ExecutionEntity execution = (ExecutionEntity) runtimeService.createExecutionQuery()
					.processInstanceId(processInstance.getId())
					.activityId(processInputModel.getWf_curActDefId())
					.singleResult();
			List<HistoricTaskInstanceEntity> historicTaskInstances =  (List)historyService.createHistoricTaskInstanceQuery().includeProcessVariables()
					.executionId(execution.getId()).taskDefinitionKey(processInputModel.getWf_curActDefId()).orderByHistoricTaskInstanceEndTime().desc().list();
			if(historicTaskInstances==null||historicTaskInstances.isEmpty()){
				throw new WorkFlowException(ExceptionErrorCode.B2057,"wf_curActDefId对应节点无法在历史任务表中找到");
			}
			HistoricTaskInstanceEntity historicTaskInstance=historicTaskInstances.get(0);
			ProcessInputModel oldprocessInputModel =(ProcessInputModel) historicTaskInstance.getProcessVariables().get(WorkFlowContants.WF_PROCESS_INPUT_VARIABLE_KEY);
			if(oldprocessInputModel.getFields().isEmpty()){
			// 设置页面fields
			processInputModel.setWf_fields(PageFieldsUtil
					.fieldsToXml(processInputModel.getFields()));
			}else{
				processInputModel.setWf_fields(PageFieldsUtil
						.fieldsToXml(oldprocessInputModel.getFields()));
			}
			workflowMap.put(WorkFlowContants.WF_FIELDS_KEY,processInputModel.getWf_fields());
			if (processInputModel.getWf_businessDataObject() != null) {
				processInputModel.getWf_variables().put(WorkFlowContants.WF_BUSINESS_DATA_OBJECT_KEY,
						processInputModel.getWf_businessDataObject());
			}else{
				processInputModel.getWf_variables().put(WorkFlowContants.WF_BUSINESS_DATA_OBJECT_KEY,
						oldprocessInputModel.getWf_businessDataObject());
			}
			workflowMap.putAll(processInputModel.getWf_variables());
			if(oldprocessInputModel.getWf_receivers()!=null){
				processInputModel.setWf_receiver(oldprocessInputModel.getWf_receiver());
			}
			processInputModel.setWf_procDefName(processInstance.getProcessDefinitionName());
			processInputModel.setWf_procDefId(processInstance.getProcessDefinitionId());
			processInputModel.setWf_sendUserId(historicTaskInstance.getSendUserId());
			processInputModel.setWf_sendUserOrgId(historicTaskInstance.getSenderOrgId());
			processInputModel.setWf_sender(historicTaskInstance.getSender());
			runtimeService.signal(execution.getId(),workflowMap);
		} catch (Exception e) {
			throw new WorkFlowException(ExceptionErrorCode.B2050,String.format(
					"流程调度失败,processInstance[%s],processInputModel[%s]",
					processInstance, processInputModel), e);
		}
		// 设置返回参数
		return processInstanceModel;
	}
	
	

}
