/*******************************************************************************
 * Copyright (c) 2004-2008 Peter Pasztor, Akos Horvath, Gergely Varro, Istvan Rath and Daniel Varro
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Peter Pasztor, Akos Horvath, Gergely Varro, Istvan Rath - initial API and implementation
 *******************************************************************************/

package org.eclipse.viatra2.gtasm.interpreter.term.rules;

import java.util.Vector;

import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.EList;
import org.eclipse.viatra2.core.IModelSpace;
import org.eclipse.viatra2.errors.VPMRuntimeException;
import org.eclipse.viatra2.gtasm.interpreter.exception.ViatraTransformationException;
import org.eclipse.viatra2.gtasm.interpreter.executionEnvironment.IExecutionEnvironment;
import org.eclipse.viatra2.gtasm.interpreter.term.internal.TermInterpreterErrorString;
import org.eclipse.viatra2.gtasm.interpreter.term.internal.TermInterpreterException;
import org.eclipse.viatra2.gtasm.patternmatcher.patterns.IPatternMatcher;
import org.eclipse.viatra2.gtasm.patternmatcher.patterns.PatternMatcherProvider;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.enums.MultiplicityKind;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.enums.ValueKind;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.terms.ASMFunctionInvocation;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.terms.Constant;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.terms.GTPatternCall;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.terms.NativeFunctionInvocation;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.terms.Term;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.terms.VariableReference;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.gt.GTPattern;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.modelmanagement.queryFunctions.Multiplicity;
import org.eclipse.viatra2.natives.ASMNativeFunction;


public class BasicTermEvaluator extends TermEvaluator {
	private static BasicTermEvaluator _instance = new BasicTermEvaluator();

	private BasicTermEvaluator() {
		;
	}

	public static BasicTermEvaluator getInstance() {
		return _instance;
	}

	/**
	 * This function evaluates the basic Terms. Constants,
	 * ASMFunctionInvocations, NativeFunctionInvocations, VeriableReferences.
	 * 
	 * The Native function invocation works for some functions, like
	 * java.util.Random.nextInt(), but fails to work for example with
	 * java.lang.Double.parseDouble(String)
	 * 
	 */
	@Override
	public Object evaluate(IExecutionEnvironment executionEnvironment,
			Term termToBeEvaluated) throws ViatraTransformationException {
		
		
		if (termToBeEvaluated instanceof Constant) {
			int kind = ((Constant) termToBeEvaluated).getKind().getValue();
			switch (kind) {
			case ValueKind.BOOLEAN:
				return Boolean.valueOf(((Constant) termToBeEvaluated)
						.getValue());
			case ValueKind.DOUBLE:
				return Double
						.valueOf(((Constant) termToBeEvaluated).getValue());
			case ValueKind.INTEGER:
				return Integer.valueOf(((Constant) termToBeEvaluated)
						.getValue());
			case ValueKind.STRING:
				return ((Constant) termToBeEvaluated).getValue();
			case ValueKind.MULTIPLICITY:
				if ("one_to_one".equals(((Constant) termToBeEvaluated)
						.getValue())) {
					return MultiplicityKind.ONE_TO_ONE_LITERAL;
				} else if ("one_to_many".equals(((Constant) termToBeEvaluated)
						.getValue())) {
					return MultiplicityKind.ONE_TO_MANY_LITERAL;
				} else if ("many_to_many".equals(((Constant) termToBeEvaluated)
						.getValue())) {
					return MultiplicityKind.MANY_TO_MANY_LITERAL;
				} else if ("many_to_one".equals(((Constant) termToBeEvaluated)
						.getValue())) {
					return MultiplicityKind.MANY_TO_ONE_LITERAL;
				}
			case ValueKind.UNDEF:
				return ValueKind.UNDEF_LITERAL;
			case ValueKind.MODELELEMENT:
				String fqn = ((Constant) termToBeEvaluated).getValue();
				// result is definitely not null
				if (fqn == null)
					{String[] context = {"Fully Qualified Name"};
					throw new TermInterpreterException(
							TermInterpreterErrorString.REF_NOT_STRING_MODELELEMENTQUERY,
							context,
							termToBeEvaluated);
					}
					
				// get the IModelElement from the manager
				IModelSpace _topmodel = executionEnvironment.getFramework()
				.getTopmodel();
				Object result = _topmodel.getModelManager().getElementByName(fqn);

				if (result != null)
					return result;
				else
					{
					String[] context = {fqn};
					throw new TermInterpreterException(
							TermInterpreterErrorString.CONSTANT_MODELELEMENT_DOESNOTEXISTS
							,context
							,termToBeEvaluated);
					}

			default:
				{String[] context = {termToBeEvaluated.getName()};
				throw new TermInterpreterException(
						TermInterpreterErrorString.UNIMP_TERM
						,context
						,termToBeEvaluated);
				}
			}
		} else if (termToBeEvaluated instanceof ASMFunctionInvocation) {
			EList<Object> evalParamList = new BasicEList<Object>();

			for (Object term : ((ASMFunctionInvocation) termToBeEvaluated)
					.getActualParameters()) {
				evalParamList.add(TermEvaluator.getInstance()
						.evaluate(executionEnvironment, (Term) term));
			}

			Object value = executionEnvironment.getValueOfASMFunction(
					((ASMFunctionInvocation) termToBeEvaluated)
							.getCalledFunction(), evalParamList);

			return (value == null) ? ValueKind.UNDEF_LITERAL : value;
		} else if (termToBeEvaluated instanceof NativeFunctionInvocation) {
			// Name of the native function
			String functionName = ((NativeFunctionInvocation) termToBeEvaluated)
					.getFunctionName();
			// array for the evaluated parameters
			Object[] parameters = new Object[((NativeFunctionInvocation) termToBeEvaluated)
					.getActualParameters().size()];

			// Evaluating each parameter
			int i = 0;
			for (Object parameterToBeEvaluated : ((NativeFunctionInvocation) termToBeEvaluated)
					.getActualParameters()) {
				Object currparameter = TermEvaluator.getInstance()
						.evaluate(executionEnvironment,
								(Term) parameterToBeEvaluated);
				// unbox java native values for native functions calls
				if (currparameter instanceof JavaNativeValue)
					parameters[i++] = ((JavaNativeValue) currparameter)
							.getValue();
				else
					parameters[i++] = currparameter;
			}

			//try {
				ASMNativeFunction _nativeFunction = executionEnvironment.getFramework()
						.getNativeFunctionManager().getNativeFunctionForName(
								functionName);
				IModelSpace _topmodel = executionEnvironment.getFramework().getTopmodel();
				Object o = null;
				//Protects the Viatra runtime from any exception thrown from the native function invocation
				try{
					o = _nativeFunction.evaluate(
									_topmodel, parameters);
					}
					catch (VPMRuntimeException e) {
						String[] context = {e.getMessage()};
						throw new TermInterpreterException(
								TermInterpreterErrorString.VPM_CORE
								,context
								,termToBeEvaluated);
					}// Any other exception that is not expected from the native ASM function
					catch(Throwable t) {
						String[] context = {functionName,t.getLocalizedMessage()};
						throw new TermInterpreterException(
								TermInterpreterErrorString.NATIVE_FUNCTION_EXCEPTION
								,context
								,termToBeEvaluated);
					}
				
				if (isASMNativeType(o))
					return o;
				else
					return new JavaNativeValue(o);
			

		} else if (termToBeEvaluated instanceof VariableReference) {
			try {
				return executionEnvironment
						.getVariableValue(((VariableReference) termToBeEvaluated)
								.getVariable());
			} catch (ViatraTransformationException e) {
				String[] context = {((VariableReference) termToBeEvaluated).getName()};
				throw new TermInterpreterException(
						TermInterpreterErrorString.EXECUTION_ENVIRONMENT_EXCEPTION
								+ e.getMessage(), context, termToBeEvaluated);
			}
		} else if (termToBeEvaluated instanceof GTPatternCall) {
			// Evaluates GTPatternCall for match. Boolean return value only.
			// ((GTPatternBody)((GTPatternCall)termToBeEvaluated).getCalledPattern().getPatternBodies().get(0)).get

			GTPattern gtPattern = ((GTPatternCall) termToBeEvaluated)
					.getCalledPattern();

			try {

				IPatternMatcher patternMatcher = PatternMatcherProvider
						.getInstance().getPatternMatcher(executionEnvironment,
								gtPattern);

				Vector<Object> patternParams = new Vector<Object>();
				for (Object term : ((GTPatternCall) termToBeEvaluated)
						.getActualParameters()) {
					patternParams.add(TermEvaluator.getInstance()
							.evaluate(executionEnvironment, (Term) term));
				}

				return patternMatcher.match(patternParams.toArray());
			} catch (ViatraTransformationException e) {
				throw e.addNewStackElement(termToBeEvaluated);
			}

		} else if (termToBeEvaluated instanceof Multiplicity) {
			return termToBeEvaluated;
		}
		// the control gets here, if a non-implemented Term was evaluated.
		String[] context = {termToBeEvaluated.getName()};
		throw new TermInterpreterException(TermInterpreterErrorString.UNIMP_TERM, context, termToBeEvaluated);

	}

}
