package com.hammurapi.reasoning.impl;

import java.util.ArrayList;

import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.ecore.EObject;

import com.hammurapi.flow.Flow;
import com.hammurapi.flow.Node;
import com.hammurapi.flow.Pin;
import com.hammurapi.flow.Transition;
import com.hammurapi.flow.runtime.impl.PassThroughNode;
import com.hammurapi.flow.runtime.impl.PassThroughTransition;

public class PassThroughOptimizer implements RuleSetFlowOptimizer {

	// TODO - Copy connection keys during optimization.
	
	@Override
	public void optimize(Flow ruleSetFlow) {		
		boolean optimized;
		Z: do {
			optimized = false;
			TreeIterator<EObject> rcit = ruleSetFlow.eAllContents();
			while (rcit.hasNext()) {
				EObject next = rcit.next();
				if (next instanceof Node) {					
					Node node = (Node) next;
					if (PassThroughNode.class.getName().equals(node.getType())) {
						Pin pin = node.getPin().get(0);
						if (pin.getInput().size()==1) {
							Transition input = pin.getInput().get(0);
							if (PassThroughTransition.class.getName().equals(input.getType())) {
								for (Transition output: new ArrayList<Transition>(pin.getOutput())) {
									output.setFromPin(input.getFromPin());
								}
								input.setFromPin(null);
								ruleSetFlow.getFlowElement().remove(input);
								ruleSetFlow.getFlowElement().remove(node);
								optimized = true;
								continue Z;
							}
						}
						
						if (pin.getOutput().size()==1) {
							Transition output = pin.getOutput().get(0);
							if (PassThroughTransition.class.getName().equals(output.getType())) {
								for (Transition input: new ArrayList<Transition>(pin.getInput())) {
									input.setToPin(output.getToPin());
								}
								output.setToPin(null);
								ruleSetFlow.getFlowElement().remove(output);
								ruleSetFlow.getFlowElement().remove(node);
								optimized = true;
								continue Z;
							}
						}
					}
				}
			}						
		} while (optimized);		
	}
	
	@Override
	public int getOrder() {
		return 0;
	}

}
