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

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

import org.activiti.bpmn.model.BpmnModel;
import org.activiti.bpmn.model.FlowElement;
import org.activiti.bpmn.model.FlowNode;
import org.activiti.bpmn.model.SequenceFlow;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.leanwo.activiti.exception.WorkflowException;
import com.leanwo.activiti.service.base.PreviousUserSelectCondition;
import com.leanwo.activiti.service.base.PreviousUserSelectService;

public class PreviousUserSelectServiceImpl implements PreviousUserSelectService {

	private BpmnModel bpmnModel = null;
	
	private static Logger logger = LoggerFactory.getLogger(PreviousUserSelectServiceImpl.class);
	
	private Map<String, Integer> nodeIdChecked = null;
	
	public PreviousUserSelectServiceImpl(BpmnModel bpmnModel) {
		this.bpmnModel = bpmnModel;
		this.nodeIdChecked = new HashMap<String, Integer>();
	}
	
	
	@Override
	public List<PreviousUserSelectCondition> getConditions(String startNodeId, String stopNodeId) {
		List<PreviousUserSelectCondition> previousUserSelectConditions = getConditionList(startNodeId, stopNodeId, null);
		return previousUserSelectConditions;
	}
	
	private List<PreviousUserSelectCondition> getConditionList(String startNodeId, String stopNodeId, List<String> previousConditions) {
		
		if(nodeIdChecked.containsKey(startNodeId)) {
			Integer count = nodeIdChecked.get(startNodeId);
			nodeIdChecked.put(startNodeId, count + 1);
		}else {
			nodeIdChecked.put(startNodeId, 1);
		}
		
		if(nodeIdChecked.get(startNodeId) > 100) {
			throw new WorkflowException("流程存在无限循环。请检查节点:" + startNodeId);
		}
		
		FlowElement flowElement = bpmnModel.getFlowElement(startNodeId);
		if(flowElement == null) {
			return null;
		}
		
		List<PreviousUserSelectCondition> previousUserSelectConditions = null;
		
		if(FlowNode.class.isInstance(flowElement)) {
			FlowNode flowNode = (FlowNode) flowElement;
			List<SequenceFlow> outgoingFlows = flowNode.getOutgoingFlows();
			if(outgoingFlows != null) {
				for(SequenceFlow outgoingFlow : outgoingFlows) {
					FlowElement nextFlowElement = outgoingFlow.getTargetFlowElement();//下一节点
					if(previousUserSelectConditions == null) {
						previousUserSelectConditions = new ArrayList<PreviousUserSelectCondition>();
					}
					String conditionExpression = outgoingFlow.getConditionExpression();
					conditionExpression = (conditionExpression == null) ? "" : conditionExpression;
					PreviousUserSelectCondition previousUserSelectCondition = new PreviousUserSelectCondition();
					List<String> previousConditionsNew = new ArrayList<String>();
					if(previousConditions != null && previousConditions.size() > 0) {
						previousConditions.forEach(previousCondition -> {
							previousConditionsNew.add(previousCondition);
						});
					}
					previousConditionsNew.add(conditionExpression);
					previousUserSelectCondition.setPreviousConditions(previousConditionsNew);
					if(nextFlowElement.getId() != null && nextFlowElement.getId().equals(stopNodeId)) {
						previousUserSelectCondition.setStopFlag(true);
						previousUserSelectConditions.add(previousUserSelectCondition);
					}else {
						previousUserSelectCondition.setStopFlag(false);
						List<PreviousUserSelectCondition> subNextNodes = getConditionList(nextFlowElement.getId(), stopNodeId, previousConditionsNew);
						if(subNextNodes != null) {
							for(PreviousUserSelectCondition subNextNode : subNextNodes) {
//								previousUserSelectConditions.add(subNextNode);
								if(subNextNode.isStopFlag() == true) {
									previousUserSelectConditions.add(subNextNode);
								}else {
									logger.debug("忽略节点：" + subNextNode.toString());
								}
							}
						}
					}
				}
			}
		} else {
			logger.debug("不需要校验的节点：" + flowElement.toString());
		}
		
		return previousUserSelectConditions;
	}
}
