package com.blueland.ebpm.engine.core.service;

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

import com.blueland.bpm.engine.core.service.ProcessDefinitionService;
import com.blueland.bpm.engine.core.service.ProcessExecuteService;
import com.blueland.bpm.engine.core.service.ProcessInstanceService;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ContextConfiguration;

import com.blueland.bpm.common.util.DateUtil;
import com.blueland.ebpm.engine.BaseWfServiceTest;
import com.blueland.bpm.engine.core.model.ActivityDefinitionModel;
import com.blueland.bpm.engine.core.model.ActivityInstanceModel;
import com.blueland.bpm.engine.core.model.ActivityReceiverModel;
import com.blueland.bpm.engine.core.model.BusinessDataObject;
import com.blueland.bpm.engine.core.model.ProcessDefinitionModel;
import com.blueland.bpm.engine.core.model.ProcessInputModel;
import com.blueland.bpm.engine.core.model.ProcessInstanceModel;
import com.blueland.bpm.engine.util.WorkFlowContants;
import org.springframework.test.context.junit4.SpringRunner;

@SpringBootTest
@RunWith(SpringRunner.class)
public class ProcessExecuteServiceTest extends BaseWfServiceTest {
	@Autowired
	private ProcessExecuteService processExecuteService;
	@Autowired
	private ProcessInstanceService processInstanceService;
	@Autowired
	private ProcessDefinitionService processDefinitionService;
	public void addedProcessInputModel(ProcessInputModel communicate){
		ProcessDefinitionModel processDefinitionModel=processDefinitionService.getProcessDefBykey(communicate.getWf_procDefKey());
		communicate.setWf_appId(processDefinitionModel.getTenantId());
		communicate.setWf_procDefId(processDefinitionModel.getProcDefId());
	}
	@Test
	/**
	 * 起草流程
	 */
	public void startProcess() {
		ProcessInputModel communicate = new ProcessInputModel();
		communicate.setWf_procDefKey("test_pt");
		communicate.setWf_curActDefId("nigao");
		communicate.setWf_actionType(WorkFlowContants.ACTION_TYPE_LAUCH_PROCESS);
		communicate.setWf_uniteworkUrl("http");
		communicate.setWf_sendUserId("gaof0709");
		communicate.setWf_sendUserOrgId("204300015350");
	
		ProcessDefinitionModel processDefinitionModel=processDefinitionService.getProcessDefBykey(communicate.getWf_procDefKey());
		communicate.setWf_procTitle("单元测试["+processDefinitionModel.getProcDefName()+"]"+DateUtil.getNowDate());
		communicate.setWf_appId(processDefinitionModel.getTenantId());
		communicate.setWf_procDefId(processDefinitionModel.getProcDefId());
		Map<String,Object> result=processExecuteService.nextExecute(communicate);
	}
	
	@Test
	/**
	 * 起草流程
	 */
	public void startSubProcess() {
		ProcessInputModel communicate = new ProcessInputModel();
		communicate.setWf_procTitle("测试子流程传bizkey2");
		communicate.setWf_procDefId("testparentflow:1:83de1070-ff81-11e4-9da0-68f72803f161");
		communicate.setWf_procDefKey("testparentflow");
		communicate.setWf_curActDefId("sid-19F5D9E3-BBAD-4F8E-A0E7-5E74991EB19C");
		communicate.setWf_actionType(WorkFlowContants.ACTION_TYPE_LAUCH_PROCESS);
		communicate.setWf_uniteworkUrl("http");
		communicate.setWf_sendUserId("gaof0709");
		communicate.setWf_sendUserOrgId("204300015350");
		List<ActivityReceiverModel> acts=new ArrayList<ActivityReceiverModel>();
		ActivityReceiverModel act1=new ActivityReceiverModel();
		act1.setReceiveUserId("gaof0709");
		act1.setReceiveUserOrgId("204300015350");
		act1.setSubBusinessKey("1");
		ActivityReceiverModel act2=new ActivityReceiverModel();
		act2.setReceiveUserId("zhangshl0215");
		act2.setReceiveUserOrgId("204300015552");
		act2.setSubBusinessKey("2");
		acts.add(act1);
		acts.add(act2);
		communicate.setWf_receivers(acts);
		
		Map<String,Object> result=processExecuteService.nextExecute(communicate);
		System.out.println(result);
	}

	// @Test
	/**
	 * 运行时暂存任务
	 */
	public void tempSaveTask() {
		Map fieldsMap = new HashMap();
		fieldsMap.put("userId", "1w111");
		fieldsMap.put("userName", "龙文1221");
		ProcessInputModel communicate = new ProcessInputModel();
		communicate.setFields(fieldsMap);
		communicate.setWf_curComment("我测试下暂存啊8999");
		communicate
				.setWf_actionType(WorkFlowContants.ACTION_TYPE_SAVE_ACTIVITY);
		communicate.setWf_curActInstId("7710");
		communicate.setWf_sender("zhuguanlingdao");
		processExecuteService.nextExecute(communicate);
	}

	// @Test
	/**
	 * 起草流程-直接暂存任务
	 */
	public void lauchTempSaveTask() {
		Map fieldsMap = new HashMap();
		fieldsMap.put("userId", "1w111");
		fieldsMap.put("userName", "龙文1221");
		ProcessInputModel communicate = new ProcessInputModel();
		communicate.setWf_procTitle("测试请假流程1");
		communicate.setWf_procDefId("my-leave-manual:1:15904");
		communicate.setWf_procDefKey("my-leave");
		communicate.setWf_sender("longwen");
		communicate.setFields(fieldsMap);
		communicate.setWf_curComment("我测试下新建暂存啊");
		communicate
				.setWf_actionType(WorkFlowContants.ACTION_TYPE_SAVE_ACTIVITY);
		processExecuteService.nextExecute(communicate);
	}

	// @Test
	/**
	 * 作废流程
	 */
	public void cancelProcess() {
		ProcessInputModel communicate = new ProcessInputModel();
		communicate.setWf_procTitle("测试请假流程1");
		communicate.setWf_procInstId("11901");
		communicate.setWf_curActInstId("11905");
		communicate
				.setWf_actionType(WorkFlowContants.ACTION_TYPE_CANCEL_PROCESS);
		communicate.setWf_sender("longwen");
		processExecuteService.nextExecute(communicate);
	}

	@Test
	/**
	 * 回撤流程
	 * 
	 * @throws Exception
	 */
	public void recallActivity() throws Exception {
		Map fieldsMap = new HashMap();
		fieldsMap.put("userId", "1w111");
		fieldsMap.put("userName", "龙文1221");
		ProcessInputModel communicate = new ProcessInputModel();
		communicate.setFields(fieldsMap);
		
		communicate.setWf_procTitle("3df");
		communicate.setWf_procDefId("DEMO_SYS_MULTI:1:6fde0967-25ec-11e5-b07a-68f72803f161");
		communicate.setWf_procInstId("c185143e-b9a3-11e5-bc59-005056c00001");
		communicate.setWf_curActInstId("e682e026-b9a4-11e5-bc59-005056c00001");
		communicate.setWf_actionType(WorkFlowContants.ACTION_TYPE_CALLBACK_PREV_ACTIVITY);
		communicate.setWf_sendUserOrgId("wugf1202");
		communicate.setWf_sendUserOrgId("204300012599");
		processExecuteService.nextExecute(communicate);

	}

	
	 
	 

	 @Test
	/**
	 * 跳转任一没有连线的环节（必须是流程定义中存在的环节,当前环节与目标环节可以不存在连线）
	 * 
	 * @throws Exception
	 */
	public void rejectActivityExecutor() throws Exception {
		ProcessInputModel communicate = new ProcessInputModel();
		communicate.setWf_procDefId("test_pt:3:f20a5056-f9e0-11e4-9e7c-68f72803f161");
		communicate.setWf_procTitle("46ggg");
		communicate.setWf_procInstId("329b8702-23be-11e5-a759-68f72803f161");
		communicate.setWf_curActInstId("5ddbf4f7-23bf-11e5-a759-68f72803f161");
		communicate.setWf_curActDefId("deptsh");

		communicate.setWf_actionType(WorkFlowContants.ACTION_TYPE_REJECT_ACTIVITY);
		communicate.setWf_nextActDefId("fgldsp");
		communicate.setWf_sendUserId("lidy0731");
		communicate.setWf_sendUserOrgId("204300015350");
		List activityReceiverModels=new ArrayList();
		ActivityReceiverModel activityReceiverModel=new ActivityReceiverModel();
		activityReceiverModel.setReceiveUserId("gaof0709");
		activityReceiverModel.setReceiveUserOrgId("204300015350");
		activityReceiverModels.add(activityReceiverModel);
		communicate.setWf_receivers(activityReceiverModels);
		processExecuteService.nextExecute(communicate);

	}

	@Test
	/**
	 * 测试条件网关
	 * 
	 * @throws Exception
	 */
	public void testConditionActivity() throws Exception {
		Map<String,Object> fieldsMap = new HashMap<String,Object>();
		fieldsMap.put("prince",2000);
		Map<String, Object> resultMap=start("test_expall",fieldsMap);
		ProcessInstanceModel processInstanceModel=(ProcessInstanceModel) resultMap.get("processInstanceModel");
		Assert.assertNotNull(processInstanceModel);
		Assert.assertEquals("分管领导审批", processInstanceModel.getNextActivity().get(0).getActDefName());
		resultMap=next(processInstanceModel.getNextActivity().get(0).getActInstId());
		processInstanceModel=(ProcessInstanceModel) resultMap.get("processInstanceModel");
		Assert.assertNotNull(processInstanceModel);
		Assert.assertNotNull(processInstanceModel.getFinishTime());
	}
	
	
	@Test
	/**
	 * 测试等待任务
	 */
	public void testSignalReceiveTask() {
		Map<String, Object> resultMap=start("test_wait_task",null);
		ProcessInstanceModel processInstanceModel=(ProcessInstanceModel) resultMap.get("processInstanceModel");
		Assert.assertNotNull(processInstanceModel);
		
		Map fieldsMap = new HashMap();
		fieldsMap.put("userId", "1w");
		fieldsMap.put("userName", "龙文");
		ProcessInputModel communicate = new ProcessInputModel();
		communicate.setWf_procTitle(processInstanceModel.getProcTitle());
		communicate.setWf_procInstId(processInstanceModel.getProcInstId());
		communicate.setWf_curActDefId("sid-393FB09C-32D8-4FAA-97B0-8BF779BFCFDB");
		communicate.setWf_actionType(WorkFlowContants.ACTION_TYPE_SIGNAL_RECEIVE_ACTIVITY);
		
		communicate.setFields(fieldsMap);
		BusinessDataObject businessDataObject=new BusinessDataObject();
		businessDataObject.setBizData("123");
		businessDataObject.setObjectType("aa");
		communicate.setWf_businessDataObject(businessDataObject);
		List<ActivityReceiverModel> a=new ArrayList<ActivityReceiverModel>();
		ActivityReceiverModel activityReceiverModel=new ActivityReceiverModel();
		activityReceiverModel.setReceiveUserId("zhangshl0215");
		activityReceiverModel.setReceiveUserOrgId("204300015552");
		a.add(activityReceiverModel);
		communicate.setWf_receivers(a);
		resultMap=processExecuteService.nextExecute(communicate);
		List<ActivityInstanceModel> tasks = processInstanceService.getTopProcessAllTasks(communicate.getWf_procInstId());
		Assert.assertEquals(1, tasks.size());
		resultMap=next(tasks.get(0).getActInstId());
		processInstanceModel=(ProcessInstanceModel) resultMap.get("processInstanceModel");
		Assert.assertNotNull(processInstanceModel);
		Assert.assertNotNull(processInstanceModel.getFinishTime());
	}
	@Test
	/**
	 * 跳转任一没有连线的环节（必须是流程定义中存在的环节,当前环节与目标环节可以不存在连线）
	 * 
	 * @throws Exception
	 */
	public void executeAnyNextActivity() throws Exception {
		next("6f4a4ed2-5073-11e5-90a0-68f72803f161");
	}

	private Map<String, Object> next(String taskId) {
		ActivityInstanceModel task = processInstanceService.getTask(taskId);
		ProcessInputModel communicate = new ProcessInputModel();
		communicate.setWf_procTitle(task.getProcTitle());
		communicate.setWf_procInstId(task.getProcInstId());
		communicate.setWf_procDefId(task.getProcDefId());
		communicate.setWf_curActInstId(task.getActInstId());
		communicate.setWf_curActDefId(task.getActDefId());
		communicate.setWf_uniteworkUrl("http");
		communicate.setWf_sendUserId(task.getReceiverUserId());
		communicate.setWf_sendUserOrgId(task.getReceiverOrgId());
		communicate
				.setWf_actionType(WorkFlowContants.ACTION_TYPE_EXECUTE_ACTIVITY);
		communicate.setWf_curComment("测试超长意见测试超长意见测试超长意见测试超长意见测试超长意见测试超长意见测试超长意见测试超长意见测试超长意见测试超长意见测试超长意见测试超长意见测试超长意见测试超长意见测试超长意见测试超长意见测试超长意见测试超长意见测试超长意见测试超长意见测试超长意见测试超长意见测试超长意见测试超长意见测试超长意见测试超长意见测试超长意见测试超长意见测试超长意见测试超长意见测试超长意见测试超长意见测试超长意见测试超长意见测试超长意见测试超长意见测试超长意见");
		return processExecuteService.nextExecute(communicate);
	}
	
	
	private Map<String, Object> start(String procDefKey,Map fieldMap){
		ProcessInputModel communicate = new ProcessInputModel();
		communicate.setWf_procDefKey(procDefKey);
		communicate.setWf_actionType(WorkFlowContants.ACTION_TYPE_LAUCH_PROCESS);
		communicate.setWf_uniteworkUrl("http");
		communicate.setWf_sendUserId("gaof0709");
		communicate.setWf_sendUserOrgId("204300015350");
		
		ProcessDefinitionModel processDefinitionModel=processDefinitionService.getProcessDefBykey(communicate.getWf_procDefKey());
		ActivityDefinitionModel startAct=processDefinitionService.getStartActivity(processDefinitionModel.getProcDefId());
		communicate.setWf_curActDefId(startAct.getActDefId());
		
		communicate.setWf_procTitle("单元测试["+processDefinitionModel.getProcDefName()+"]"+DateUtil.convertDateToString("yyyyMMddHHmmss", new Date()));
		communicate.setWf_appId(processDefinitionModel.getTenantId());
		communicate.setWf_procDefId(processDefinitionModel.getProcDefId());
		communicate.setFields(fieldMap);
		return processExecuteService.nextExecute(communicate);
	}
}
