/*******************************************************************************
 * 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.impl.executionEnvironment;

import java.util.Comparator;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.Vector;

import org.eclipse.emf.common.util.EList;
import org.eclipse.viatra2.framework.IFramework;
import org.eclipse.viatra2.gtasm.interpreter.exception.ASMInterpreterErrorStrings;
import org.eclipse.viatra2.gtasm.interpreter.exception.ViatraTransformationException;
import org.eclipse.viatra2.gtasm.interpreter.executionEnvironment.ASMFunctionContent;
import org.eclipse.viatra2.gtasm.interpreter.executionEnvironment.IExecutionEnvironment;
import org.eclipse.viatra2.gtasm.interpreter.impl.machine.ASMInterpreterException;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.definitions.ASMFunction;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.definitions.Variable;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.terms.ASMFunctionInvocation;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.terms.FunctionInvocation;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.terms.Term;
import org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.terms.VariableReference;


public class ExecutionEnvironment implements IExecutionEnvironment {
	/**
	 * This class is used to handle the execution environment when running an
	 * ASM
	 * 
	 * If the TermEvaluator creates a sub-execution environment (stack) for its
	 * operation for example at a function call, the values may change, the
	 * variables and everything that changed needs to be refreshed
	 * 
	 * @author Peter Pasztor
	 * 
	 */
	protected IExecutionEnvironment parentExecutionEnvironment;
	protected IFramework framework;

	/*
	 * protected TermHandler termHandler; protected PatternBuilder
	 * patternBuilder;
	 */

	// protected SimpleModelSpace modelSpace;
	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.viatra2.gtasm.interpreter.executionEnvironment.IExecutionEnvironment#getFramework()
	 */
	public IFramework getFramework() {
		return framework;

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.viatra2.gtasm.interpreter.executionEnvironment.IExecutionEnvironment#onBegin(java.util.Map)
	 */
	public void onBegin(Map<Variable, Object> variables) {
		;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.viatra2.gtasm.interpreter.executionEnvironment.IExecutionEnvironment#onTerminate()
	 */
	public Map<Variable, Object> onTerminate() {
		return null;
	}

	// protected Hashtable<Variable, Object> variableValues;
	protected Map<Variable, Object> variableValues;

	protected ASMFunctionContent ASMFunctionValues;

	public ExecutionEnvironment(IFramework framework) {
		parentExecutionEnvironment = null;

		// variableValues = new Hashtable<Variable, Object>();
		variableValues = new TreeMap<Variable, Object>(
				new Comparator<Variable>() {

					/*
					 * XXX Istvan: is it valid to compare variables in an
					 * executionenvironment by their name?
					 */

					public int compare(Variable o1, Variable o2) {
						// if (o1 instanceof PatternVariable || o2 instanceof
						// PatternVariable)
						// return o1.getName().compareTo(o2.getName());
						// else
						{
							int h_o1 = o1.hashCode();
							int h_o2 = o2.hashCode();
							if (h_o1 == h_o2)
								return 0;
							else if (h_o1 > h_o2)
								return 1;
							else
								return -1;
						}

					}
				});
		ASMFunctionValues = ASMFunctionContent.getInstance();

		this.framework = framework;
	}

	public ExecutionEnvironment(IExecutionEnvironment parent) {
		parentExecutionEnvironment = parent;

		variableValues = new Hashtable<Variable, Object>(parent
				.getVariableValues());
		ASMFunctionValues = ASMFunctionContent.getInstance();
		framework = parent.getFramework();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.viatra2.gtasm.interpreter.executionEnvironment.IExecutionEnvironment#getValueOfASMFunction(org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.definitions.ASMFunction,
	 *      org.eclipse.emf.common.util.EList)
	 */
	public Object getValueOfASMFunction(ASMFunction asmFunction, EList<Object> location) {
		HashMap<EList<Object>, Object> af = ASMFunctionContent.getInstance().get(
				asmFunction);
		if (af == null)
			return null;
		return af.get(location);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.viatra2.gtasm.interpreter.executionEnvironment.IExecutionEnvironment#updateASMFunction(org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.definitions.ASMFunction,
	 *      org.eclipse.emf.common.util.EList, java.lang.Object)
	 */
	public void updateASMFunction(ASMFunction asmFunction, EList<Object> location,
			Object value) throws ViatraTransformationException {
		if (ASMFunctionValues.get(asmFunction) != null) {
			ASMFunctionValues.get(asmFunction).put(location, value);
			// notify value listeners
			ASMFunctionValues.notifyListeners(asmFunction, location, value);
		} else {
			String[] context = {asmFunction.getName()};
			throw new ASMInterpreterException(
					ASMInterpreterErrorStrings.UPDATE_NONEXISTENT_ASMFUNCTION
							, context
							, asmFunction);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.viatra2.gtasm.interpreter.executionEnvironment.IExecutionEnvironment#addVariable(org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.definitions.Variable,
	 *      java.lang.Object)
	 */
	public void addVariable(Variable key, Object value)
			throws ViatraTransformationException {
		if (variableValues.containsKey(key))
			{
			String[] context = {key.getName()};
			throw new ASMInterpreterException(ASMInterpreterErrorStrings.ADD_EXISTING_VAR
					, context
					, key);
			}
		else
			variableValues.put(key, value);
	}

	// This is necessary when returning from another ExecutionEnvironment
	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.viatra2.gtasm.interpreter.executionEnvironment.IExecutionEnvironment#updateVariables(java.util.Map)
	 */
	public void updateVariables(Map<Variable, Object> changedVariables) {
		variableValues.putAll(changedVariables);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.viatra2.gtasm.interpreter.executionEnvironment.IExecutionEnvironment#getVariableValue(org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.definitions.Variable)
	 */
	public Object getVariableValue(Variable variable)
			throws ViatraTransformationException {
		// The local variables are more likely to be accessed, and are not so
		// many as the global ones
		if (variableValues.containsKey(variable))
			return variableValues.get(variable);
		else
			{
			String[] context = {variable.getName()};
			throw new ASMInterpreterException(
					ASMInterpreterErrorStrings.VALUE_OF_NOT_EXISTING_VAR
					,context
					,null);
			}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.viatra2.gtasm.interpreter.executionEnvironment.IExecutionEnvironment#setVariableValue(org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.definitions.Variable,
	 *      java.lang.Object)
	 */
	public void setVariableValue(Variable variable, Object value)
			throws ViatraTransformationException { // The Variable itself doesn't
												// change, just the value
		if (variableValues.containsKey(variable)) {
			// This is the easy case, just modify the value
			variableValues.put(variable, value);
		} else
			{
			String context[] = {variable.getName()};
			throw new ASMInterpreterException(
					ASMInterpreterErrorStrings.SET_VALUE_NOT_EXISTING_VAR
							, context
							, null);
			}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.viatra2.gtasm.interpreter.executionEnvironment.IExecutionEnvironment#getVariableValues()
	 */
	public Map<Variable, Object> getVariableValues() {
		return variableValues;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.viatra2.gtasm.interpreter.executionEnvironment.IExecutionEnvironment#fetchVariableVariations(java.util.HashMap,
	 *      org.eclipse.viatra2.gtasmmodel.gtasm.metamodel.asm.terms.Term)
	 */
	public void fetchVariableVariations(
			HashMap<Variable, Vector<Object>> possibleVariableValues,
			Term termToBeEvaluated) {
		Integer index;
		Set<EList<Object>> keys;

		Set<Variable> variables = possibleVariableValues.keySet();
		if (termToBeEvaluated instanceof FunctionInvocation) {
			// Get into the parameters only
			if (termToBeEvaluated instanceof ASMFunctionInvocation) {

				// Here happens the real fetching of possibly good variable
				// values
				((ASMFunctionInvocation) termToBeEvaluated)
						.getActualParameters();
				for (Object parameter : ((ASMFunctionInvocation) termToBeEvaluated)
						.getActualParameters()) {

					// For every parameter, we check whether it's a variable
					// from the list, or not.
					if (parameter instanceof VariableReference) {
						if (variables.contains(((VariableReference) parameter)
								.getVariable())) {

							// We found one. Now we must get the possible
							// values.
							// (parameter is now an instance of type Variable!)

							index = ((ASMFunctionInvocation) termToBeEvaluated)
									.getActualParameters().indexOf(parameter);

							keys = this.ASMFunctionValues.get(
									((ASMFunctionInvocation) termToBeEvaluated)
											.getCalledFunction()).keySet();

							for (EList<Object> key : keys) {

								// Now we get a possible value (parameter holds
								// the Variable!)
								// Only one appearance allowed, hence the check
								// It wastes time, but
								// wastes much less time than having to
								// re-evaluate the term again
								// and again for the same parameters

								if (!possibleVariableValues.get(
										((VariableReference) parameter)
												.getVariable()).contains(
										key.get(index)))
									possibleVariableValues.get(
											((VariableReference) parameter)
													.getVariable()).add(
											key.get(index));
							}
						}
					} else if (parameter instanceof FunctionInvocation) {
						// It might be nested. Further investigation required.
						fetchVariableVariations(possibleVariableValues,
								((Term) parameter));
					}
				}
			} // end of ASMFunctionInvocation
			else {
				// Other function invocations -- like operations etc.
				// We must look at the operands, the operation itself is not
				// important,
				// the term evaluator will take care of that. It might be
				// necessary to
				// recursively process them, to be able to process not trivial
				// conditions.
				for (Object parameter : ((FunctionInvocation) termToBeEvaluated)
						.getActualParameters()) {
					this.fetchVariableVariations(possibleVariableValues,
							((Term) parameter));
				}
			}
		} else {
			// There is a problem here, since only FunctionInvocations are
			// allowed...

		}
	}
}
