/*
 * 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.mdd4soa.trans.uml2smm.data;

import java.util.List;

import org.antlr.runtime.ANTLRStringStream;
import org.antlr.runtime.CharStream;
import org.antlr.runtime.CommonTokenStream;
import org.antlr.runtime.RecognitionException;

import eu.mdd4soa.smm.behaviour.ServiceActivity;
import eu.mdd4soa.smm.data.LeftHandSideExpression;
import eu.mdd4soa.smm.data.RightHandSideExpression;
import eu.mdd4soa.smm.data.Statement;
import eu.mdd4soa.smm.exception.TransformationException;
import eu.mdd4soa.smm.statik.SMMType;

public class ParserAccess {

	/**
	 * 
	 * The expression is a right-hand side expression.
	 * 
	 * 
	 * @param context
	 * @param typeOfInputPin
	 * @param receivePin
	 * @return
	 * @throws TransformationException
	 */
	public static RightHandSideExpression parseSendPin(ServiceActivity context, String sendPinText) throws TransformationException {

		if (context == null)
			throw new NullPointerException("Context may not be null when calling parseSendPin.");

		DataParser parser= ParserAccess.createParserForInput(context, sendPinText);

		try {
			return parser.rightHandExp();

		} catch (RecognitionException e) {
			throw new TransformationException("Error during parsing of RHS expression: " + sendPinText, e);
		}

	}


	/**
	 * The left-hand side must be a variable or field. If it is a variable, we
	 * can create it on-the-fly, hence the type. If it is a field, the variable
	 * must exist.
	 * 
	 * @param context
	 * @param receivePin
	 * @return
	 * @throws TransformationException
	 */
	public static LeftHandSideExpression parseReceivePin(ServiceActivity context, SMMType type, String receivePinText) throws TransformationException {

		if (context == null)
			throw new NullPointerException("Context may not be null when calling parseReceivePin.");

		DataParser parser= ParserAccess.createParserForInput(context, receivePinText);

		try {
			return parser.leftHandExp(type);

		} catch (RecognitionException e) {
			throw new TransformationException("Error during parsing of LHS expression: " + receivePinText, e);
		}
	}

	public static RightHandSideExpression parseGuard(ServiceActivity context, String guard) throws TransformationException {
		DataParser parser= ParserAccess.createParserForInput(context, guard);

		try {
			return parser.rightHandExp();

		} catch (RecognitionException e) {
			throw new TransformationException("Error during parsing of guard expression: " + guard, e);
		}
	}

	public static List<Statement> parseDataAction(ServiceActivity context, String dataHandlingBody) throws TransformationException {
		DataParser parser= ParserAccess.createParserForInput(context, dataHandlingBody);

		try {
			List<Statement> data= parser.data();
			return data;
		} catch (RecognitionException e) {
			throw new TransformationException("Error during parsing of data expression: " + dataHandlingBody, e);
		}
	}

	private static DataParser createParserForInput(ServiceActivity currentLocation, String input) {
		CharStream stream= new ANTLRStringStream(input);
		DataLexer lexer= new DataLexer(stream);
		CommonTokenStream tokens= new CommonTokenStream(lexer);
		DataParser parser= new DataParser(tokens);
		parser.setServiceActivity(currentLocation);
		return parser;
	}
}
