package com.artfess.activiti.def.service.impl;

import com.artfess.base.util.BeanUtils;
import com.artfess.bpm.api.service.ActiviService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.impl.RepositoryServiceImpl;
import org.activiti.engine.impl.bpmn.behavior.ParallelGatewayActivityBehavior;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.impl.pvm.PvmActivity;
import org.activiti.engine.impl.pvm.PvmTransition;
import org.activiti.engine.impl.pvm.delegate.ActivityBehavior;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

@Component
public class ActiviServiceImpl implements ActiviService{

	@Resource
	RepositoryService repositoryService;

	/**
	 * desNodeId目标节点是否在同步内
	 * @param actDefId
	 * @param curNodeId 运行的节点
	 * @param desNodeId 驳回的节点
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	@Override
	public boolean inGateway(String actDefId,String curNodeId, String desNodeId) throws Exception {
		ProcessDefinitionEntity processDefinition = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService).getDeployedProcessDefinition(actDefId);
		ActivityImpl curAct= processDefinition.findActivity(curNodeId);
		List<PvmTransition> incomingTransitions = curAct.getIncomingTransitions();
		while(BeanUtils.isNotEmpty(incomingTransitions)) {
			List<PvmTransition> tmp =incomingTransitions;
			incomingTransitions = new ArrayList<PvmTransition>();
			for (PvmTransition pvmTransition : tmp) {
				PvmActivity source = pvmTransition.getSource();
				String id = source.getId();
				if(desNodeId.equals(id)) {
					return true;
				}
				if(source instanceof ActivityImpl) {
					ActivityImpl activityImpl = (ActivityImpl) source;
					ActivityBehavior activityBehavior = activityImpl.getActivityBehavior();
					if(activityBehavior instanceof ParallelGatewayActivityBehavior) {
						return false;
					}
				}
				List<PvmTransition> incomingTransitions2 = source.getIncomingTransitions();
				if(BeanUtils.isNotEmpty(incomingTransitions)) {
					incomingTransitions.addAll(incomingTransitions2);
				}
			}
		}
		return true;
	}

}
