/*
 * This file has been developed at the University of Munich, Chair for Programming & Software Engineering.
 * 
 * This file is licensed under the Eclipse Public License (EPL) 1.0
 * 
 */
package eu.uml4soa.utbm.vnserver;

import java.util.List;

import net.miowb.model.mio.Action;
import net.miowb.model.mio.ModalIOAutomaton;
import net.miowb.model.mio.State;
import net.miowb.operations.compatibility.IOCompatibilityImplementation;
import net.miowb.operations.compatibility.IOCompatibilityImplementation.CompatibilityType;
import net.miowb.workbench.operations.model.StatePair;
import net.miowb.workbench.operations.result.CompatibilityResult;

import org.eclipse.uml2.uml.Model;
import org.eclipse.uml2.uml.ProtocolStateMachine;

import eu.uml4soa.utbm.u2m.SemanticsException;
import eu.uml4soa.utbm.u2m.semantics.ProtocolSemanticsFunction;

public class ServerCompatibilityChecker extends AbstractChecker {

	public ServerCompatibilityChecker(String theory, String fileName) {
		super(theory, fileName);
	}

	public boolean check() {

		Model model= loadModel();

		ProtocolStateMachine psm1= getPSM(model, getLeftName());
		ProtocolStateMachine psm2= getPSM(model, getRightName());

		if (psm1 == null || psm2 == null) {
			setResult("Could not find the state machines in EMF model.");
			return false;
		}

		try {
			ProtocolSemanticsFunction f= new ProtocolSemanticsFunction(psm1);
			f.calculateSemantics();
			ModalIOAutomaton leftSem= f.getSemantics();

			ProtocolSemanticsFunction f2= new ProtocolSemanticsFunction(psm2);
			f2.calculateSemantics();
			ModalIOAutomaton rightSem= f2.getSemantics();

			CompatibilityResult result= IOCompatibilityImplementation.verify(CompatibilityType.WEAK, leftSem, rightSem);

			if (result.areCompatible())
				return true;
			else {
				List<Action> problemActions= result.getProblemActions();
				if (problemActions != null && !problemActions.isEmpty()) {
					String temp= ServerClientConstants.ERROR_COMPATIBILITY_SIGNATURE + ServerClientConstants.SEPARATOR
							+ "Cannot check compatibility due to problematic signatures: ";
					for (Action action : problemActions) {
						temp+= action.getLabel() + " ";
					}
					setResult(temp);
				} else if (result.getProblemPair() != null) {

					String whichAutomaton= null;

					StatePair problemPair= result.getProblemPair();
					State s1= problemPair.getS1();
					State s2= problemPair.getS2();

					ModalIOAutomaton automaton= result.getProblemPath().getRelevantTransition().getAutomaton();
					if (automaton == leftSem) {
						whichAutomaton= "LEFT";
					} else {
						whichAutomaton= "RIGHT";
					}

					String actionLabel= result.getProblemPath().getRelevantTransition().getAction().getLabel();

					setResult(ServerClientConstants.ERROR_COMPATIBILITY_TRANSITION + ServerClientConstants.SEPARATOR + whichAutomaton
							+ ServerClientConstants.SEPARATOR + s1.getLabel() + ServerClientConstants.SEPARATOR + s2.getLabel()
							+ ServerClientConstants.SEPARATOR + actionLabel);

				} else {
					setResult("Unknown compatibility problem.");
				}
				return false;
			}

		} catch (SemanticsException e) {
			setResult("Could not generate semantics:" + e.getMessage());
			return false;
		}
	}
}
