/*******************************************************************************
 * Copyright (c) 2013 Christian Pontesegger and others.
 * 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:
 *     Christian Pontesegger - initial API and implementation
 *     Mathieu Velten - Bug correction
 *******************************************************************************/
package org.eclipse.ease.lang.javascript.rhino;

import java.io.InputStreamReader;
import java.net.URL;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;

import org.eclipse.ease.AbstractReplScriptEngine;
import org.eclipse.ease.IExecutionListener;
import org.eclipse.ease.Script;
import org.eclipse.ease.ScriptExecutionException;
import org.eclipse.ease.ScriptObjectType;
import org.eclipse.ease.ScriptResult;
import org.eclipse.ease.classloader.EaseClassLoader;
import org.eclipse.ease.debugging.EaseDebugFrame;
import org.eclipse.ease.debugging.IScriptDebugFrame;
import org.eclipse.ease.debugging.ScriptStackTrace;
import org.eclipse.ease.debugging.model.EaseDebugVariable;
import org.eclipse.ease.debugging.model.EaseDebugVariable.Type;
import org.eclipse.ease.lang.javascript.JavaScriptHelper;
import org.eclipse.ease.tools.RunnableWithResult;
import org.eclipse.swt.widgets.Display;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.ContextFactory;
import org.mozilla.javascript.EcmaError;
import org.mozilla.javascript.EvaluatorException;
import org.mozilla.javascript.ImporterTopLevel;
import org.mozilla.javascript.JavaScriptException;
import org.mozilla.javascript.NativeArray;
import org.mozilla.javascript.NativeFunction;
import org.mozilla.javascript.NativeJavaArray;
import org.mozilla.javascript.NativeJavaObject;
import org.mozilla.javascript.NativeObject;
import org.mozilla.javascript.RhinoException;
import org.mozilla.javascript.ScriptRuntime;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ScriptableObject;
import org.mozilla.javascript.Undefined;
import org.mozilla.javascript.WrappedException;

/**
 * A script engine to execute JavaScript code on a Rhino interpreter.
 */
public class RhinoScriptEngine extends AbstractReplScriptEngine {

	private static final EaseClassLoader CLASSLOADER;

	static {
		CLASSLOADER = new EaseClassLoader();
		// set context factory that is able to terminate script execution
		ContextFactory.initGlobal(new ObservingContextFactory());

		// set a custom class loader to find everything in the eclipse universe
		AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
			ContextFactory.getGlobal().initApplicationClassLoader(CLASSLOADER);
			return null;
		});
	}

	public static final String ENGINE_ID = "org.eclipse.ease.javascript.rhino";

	public static Context getContext() {
		Context context = Context.getCurrentContext();
		if (context == null) {
			synchronized (ContextFactory.getGlobal()) {
				context = Context.enter();
			}
		}

		return context;
	}

	/** Rhino Scope. Created when interpreter is initialized */
	private ScriptableObject fScope;

	private Context fContext;

	private int fOptimizationLevel = 9;

	private ScriptStackTrace fExceptionStackTrace = null;

	/**
	 * Creates a new Rhino interpreter.
	 */
	public RhinoScriptEngine() {
		super("Rhino");
	}

	/**
	 * Creates a new Rhino interpreter.
	 *
	 * @param name
	 *            name of interpreter (used for the jobs name)
	 */
	protected RhinoScriptEngine(final String name) {
		super(name);
	}

	public void setOptimizationLevel(final int level) {
		fOptimizationLevel = level;
	}

	@Override
	protected synchronized void setupEngine() {
		fContext = getContext();

		fContext.setGeneratingDebug(false);
		fContext.setOptimizationLevel(fOptimizationLevel);
		fContext.setDebugger(null, null);

		fScope = new ImporterTopLevel(fContext);

		// enable script termination support
		fContext.setGenerateObserverCount(true);
		fContext.setInstructionObserverThreshold(10);

		// enable JS v1.8 language constructs
		try {
			Context.class.getDeclaredField("VERSION_1_8");
			fContext.setLanguageVersion(Context.VERSION_1_8);
		} catch (final Exception e) {
			fContext.setLanguageVersion(Context.VERSION_1_7);
		}
	}

	@Override
	protected synchronized void teardownEngine() {
		// remove debugger to allow for garbage collection
		fContext.setDebugger(null, null);

		// cleanup context
		Context.exit();
		fContext = null;
		fScope = null;

		// unregister from classloader
		CLASSLOADER.unregisterEngine(this);
	}

	@Override
	protected Object execute(final Script script, final Object reference, final String fileName, final boolean uiThread) throws Throwable {
		if (uiThread) {
			// run in UI thread
			final RunnableWithResult<Object> runnable = new RunnableWithResult<Object>() {

				@Override
				public void runWithTry() throws Throwable {
					// initialize scope
					getContext().initStandardObjects(fScope);

					// call execute again, now from correct thread
					setResult(internalExecute(script, reference, fileName));
				}
			};

			Display.getDefault().syncExec(runnable);

			return runnable.getResultFromTry();

		} else
			// run in engine thread
			return internalExecute(script, reference, fileName);
	}

	private Object internalExecute(final Script script, final Object reference, final String fileName) throws Throwable {

		// remove an eventually cached terminate request
		((ObservingContextFactory) ContextFactory.getGlobal()).cancelTerminate(getContext());

		try {
			final Object result;

			// execution
			if (script.getCommand() instanceof NativeFunction)
				result = ((NativeFunction) script.getCommand()).call(getContext(), fScope, fScope, ScriptRuntime.emptyArgs);

			else if (script.getCommand() instanceof org.mozilla.javascript.Script)
				// execute anonymous functions
				result = ((org.mozilla.javascript.Script) script.getCommand()).exec(getContext(), fScope);

			else {
				final InputStreamReader codeReader = new InputStreamReader(script.getCodeStream());
				result = getContext().evaluateReader(fScope, codeReader, fileName, 1, null);
				codeReader.close();
			}

			// evaluate result
			if (result instanceof Undefined)
				return ScriptResult.VOID;

			if (result == null)
				return null;

			else if (result instanceof NativeJavaObject)
				return ((NativeJavaObject) result).unwrap();

			else if (result.getClass().getName().equals("org.mozilla.javascript.InterpretedFunction"))
				return null;

			return result;

		} catch (final RhinoException e) {
			// build exception stacktrace
			fExceptionStackTrace = getStackTrace().clone();
			if ((fExceptionStackTrace.isEmpty()) || (((script != null) && (!script.equals(fExceptionStackTrace.get(0).getScript()))))) {
				// topmost script is not what we expected, seems it was not put on the stack
				fExceptionStackTrace.add(0, new EaseDebugFrame(script, e.lineNumber(), IScriptDebugFrame.TYPE_FILE));
			}

			// now handle error
			String message = e.getMessage();
			String errorName = "Error";
			Throwable cause = null;

			if (e instanceof WrappedException) {
				final Throwable wrapped = ((WrappedException) e).getWrappedException();
				if (wrapped instanceof ScriptExecutionException)
					throw wrapped;

				else if (wrapped != null) {
					// java exception thrown
					message = wrapped.getMessage();
					errorName = "JavaError";
					cause = wrapped;
				}

			} else if (e instanceof EcmaError) {
				message = ((EcmaError) e).getErrorMessage();
				errorName = ((EcmaError) e).getName();

			} else if (e instanceof JavaScriptException) {
				// throw statement from javascript
				final Object value = ((JavaScriptException) e).getValue();
				if (value instanceof NativeJavaObject) {
					final Object unwrapped = ((NativeJavaObject) value).unwrap();
					if (unwrapped instanceof Throwable) {
						message = ((Throwable) unwrapped).getMessage();
						errorName = "JavaError";
						cause = (Throwable) unwrapped;
					} else {
						message = (unwrapped != null) ? unwrapped.toString() : null;
						errorName = "ScriptException";
					}

				} else {
					message = (((JavaScriptException) e).getValue() != null) ? ((JavaScriptException) e).getValue().toString() : null;
					errorName = "ScriptException";
				}

			} else if (e instanceof EvaluatorException) {
				// invalid syntax or similar rhino exception
				errorName = "SyntaxError";

			} else {
				message = "Error running script";
			}

			throw new ScriptExecutionException(message, e.columnNumber(), e.lineSource(), errorName, getExceptionStackTrace(), cause);
		}
	}

	public ScriptStackTrace getExceptionStackTrace() {
		return fExceptionStackTrace;
	}

	@Override
	public void terminateCurrent() {
		// typically requested by a different thread, so do not use getContext() here
		((ObservingContextFactory) ContextFactory.getGlobal()).terminate(fContext);
	}

	@Override
	public synchronized void registerJar(final URL url) {
		CLASSLOADER.registerURL(this, url);
	}

	@Override
	protected Object internalGetVariable(final String name) {
		return getVariable(fScope, name);
	}

	@Override
	protected Map<String, Object> internalGetVariables() {
		return getVariables(fScope);
	}

	public Map<String, Object> getVariables(final Scriptable scope) {
		final Map<String, Object> result = new TreeMap<>();

		// first handle parent scope
		final Scriptable parent = scope.getParentScope();
		if (parent != null)
			result.putAll(getVariables(parent));

		// local scope variables may hide parent scope variables
		for (final Object key : scope.getIds()) {
			final Object value = getVariable(scope, key.toString());
			if ((value == null) || (!value.getClass().getName().startsWith("org.mozilla.javascript.gen")))
				result.put(key.toString(), value);
		}

		return result;
	}

	private Object getVariable(final Scriptable scope, final String name) {
		return runInJobContext(new RunnableWithResult<Object>() {
			@Override
			public void run() {
				final Object value = scope.get(name, scope);
				if (value instanceof NativeJavaObject)
					setResult(((NativeJavaObject) value).unwrap());
				else
					setResult(value);
			}
		});
	}

	@Override
	protected boolean internalHasVariable(final String name) {

		return runInJobContext(new RunnableWithResult<Boolean>() {
			@Override
			public void run() {
				final Object value = fScope.get(name, fScope);
				setResult(!Scriptable.NOT_FOUND.equals(value));
			}
		});
	}

	private <T> T runInJobContext(RunnableWithResult<T> runnable) {
		if (Context.getCurrentContext() != null) {
			runnable.run();
			return runnable.getResult();
		} else {
			getContext();
			runnable.run();
			Context.exit();
			return runnable.getResult();
		}
	}

	@Override
	protected void internalSetVariable(final String name, final Object content) {
		runInJobContext(new RunnableWithResult<Boolean>() {
			@Override
			public void run() {
				if (!JavaScriptHelper.isSaveName(name))
					throw new RuntimeException("\"" + name + "\" is not a valid JavaScript variable name");

				final Scriptable scope = fScope;

				final Object jsOut = internaljavaToJS(content, scope);
				scope.put(name, scope, jsOut);
			}
		});
	}

	protected Object internaljavaToJS(final Object value, final Scriptable scope) {
		Object result = null;
		if (isPrimitiveType(value) || (value instanceof Scriptable)) {
			result = value;
		} else if (value instanceof Character) {
			result = String.valueOf(((Character) value).charValue());
		} else {
			result = getContext().getWrapFactory().wrap(getContext(), scope, value, null);
		}
		return result;

	}

	private boolean isPrimitiveType(final Object value) {
		return (value instanceof String) || (value instanceof Number) || (value instanceof Boolean);
	}

	/**
	 * Method to get the global scope of this engine.
	 *
	 * @return fScope
	 */
	public ScriptableObject getScope() {
		return fScope;
	}

	protected Context getCurrentContext() {
		return fContext;
	}

	@Override
	protected Collection<EaseDebugVariable> getDefinedVariables(Object scope) {
		final Collection<EaseDebugVariable> result = new HashSet<>();

		if (scope instanceof ImporterTopLevel) {
			final Object[] objectIDs = ((ImporterTopLevel) scope).getIds();

			for (final Object id : objectIDs) {
				final Object object = ((ImporterTopLevel) scope).get(id);
				if (acceptVariable(object)) {
					final EaseDebugVariable variable = createVariable(id.toString(), object);
					result.add(variable);
				}
			}

		} else if (scope instanceof NativeArray) {
			for (final int indexId : ((NativeArray) scope).getIndexIds()) {
				final EaseDebugVariable variable = createVariable("[" + indexId + "]", ((NativeArray) scope).get(indexId));
				result.add(variable);
			}

			for (final Object id : ((NativeArray) scope).getIds()) {
				// integers are already handled by the previous loop
				if (!(id instanceof Integer)) {
					final EaseDebugVariable variable = createVariable(id.toString(), ((NativeArray) scope).get(id));
					result.add(variable);
				}
			}

		} else if (scope instanceof NativeObject) {
			for (final Entry<String, Object> entry : getNativeChildObjects((NativeObject) scope).entrySet()) {
				final EaseDebugVariable variable = createVariable(entry.getKey(), entry.getValue());
				result.add(variable);
			}

		} else if (scope instanceof NativeJavaArray) {
			for (final Object id : ((NativeJavaArray) scope).getIds()) {
				if (id instanceof Integer) {
					final EaseDebugVariable variable = createVariable("[" + id + "]", ((NativeJavaArray) scope).get((Integer) id, (Scriptable) scope));
					result.add(variable);
				}
			}

		} else if (scope instanceof Scriptable) {
			for (final Object id : ((Scriptable) scope).getIds()) {
				final EaseDebugVariable variable = createVariable(id.toString(), ((Scriptable) scope).get(id.toString(), (Scriptable) scope));
				result.add(variable);
			}

		} else if (hasNoChildElements(scope))
			return result;

		else
			// marker that child variables should be resolved dynamically
			return null;

		return result;
	}

	private static boolean hasNoChildElements(Object scope) {
		if (scope instanceof Double)
			return true;

		if (scope == null)
			return true;

		return false;
	}

	@Override
	protected EaseDebugVariable createVariable(String name, Object value) {
		final EaseDebugVariable variable = super.createVariable(name, value);

		if (value instanceof NativeArray) {
			variable.getValue().setValueString("array[" + ((NativeArray) value).getIds().length + "]");
			variable.setType(Type.NATIVE_ARRAY);

		} else if (value instanceof NativeObject) {
			variable.getValue().setValueString("object{" + getNativeChildObjects((NativeObject) value).size() + "}");
			variable.setType(Type.NATIVE_OBJECT);

		} else if (value instanceof String) {
			try {
				if (hasVariable(name)) {
					// test for java string objects
					final Object inject = inject(name + ".length;");
					if (inject instanceof Integer)
						variable.setType(Type.NATIVE_OBJECT);
				}
			} catch (final Exception e) {
				// could not execute type check, ignore
			}
		}

		return variable;
	}

	private Map<String, Object> getNativeChildObjects(NativeObject parent) {
		final HashMap<String, Object> childObjects = new HashMap<>();

		for (final Object id : parent.getIds()) {
			final Object object = parent.get(id);
			if (acceptVariable(object))
				childObjects.put(id.toString(), object);
		}

		return childObjects;
	}

	@Override
	protected boolean acceptVariable(Object value) {
		if ((value != null) && ((value.getClass().getName().startsWith("org.mozilla.javascript.gen"))
				|| (value.getClass().getName().startsWith("org.mozilla.javascript.Arguments"))))
			return false;

		return true;
	}

	@Override
	protected String getTypeName(Object object) {
		switch (getType(object)) {
		case NATIVE_ARRAY:
			return "JavaScript Array";

		case NATIVE_OBJECT:
			return "JavaScript Object";

		case NATIVE:
			return "Generic JavaScript";

		default:
			return super.getTypeName(object);
		}
	}

	@Override
	public ScriptObjectType getType(Object object) {
		if (object != null) {
			if (object instanceof NativeArray)
				return ScriptObjectType.NATIVE_ARRAY;

			if (object instanceof NativeObject)
				return ScriptObjectType.NATIVE_OBJECT;

			if (object.getClass().getName().startsWith("org.mozilla.javascript"))
				return ScriptObjectType.NATIVE;
		}

		return super.getType(object);
	}

	@Override
	public String toString(Object object) {
		if (ScriptResult.VOID.equals(object))
			return "<undefined>";

		if (object instanceof NativeArray) {
			final ArrayList<Object> elements = new ArrayList<>();
			for (final int indexId : ((NativeArray) object).getIndexIds())
				elements.add(((NativeArray) object).get(indexId));

			return buildArrayString(elements);
		}

		if (object instanceof NativeObject)
			return buildObjectString(getNativeChildObjects((NativeObject) object));

		if (getType(object) == ScriptObjectType.NATIVE)
			return "{}";

		return super.toString(object);
	}

	@Override
	protected void notifyExecutionListeners(Script script, int status) {
		if (!getTerminateOnIdle()) {
			// high probability to run in interactive shell mode

			if (IExecutionListener.SCRIPT_END == status)
				setVariable("_", script.getResult().getResult());
		}

		super.notifyExecutionListeners(script, status);
	}
}
