/*******************************************************************************
 * Copyright (c) 2017 Christian Pontesegger and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * Contributors:
 *     Christian Pontesegger - initial API and implementation
 *******************************************************************************/
package org.eclipse.ease;

import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.eclipse.ease.debugging.model.EaseDebugLastExecutionResult;
import org.eclipse.ease.debugging.model.EaseDebugVariable;
import org.eclipse.ease.debugging.model.EaseDebugVariable.Type;

/**
 * Adds generic REPL support to the AbstractScriptEngine.
 */
public abstract class AbstractReplScriptEngine extends AbstractScriptEngine implements IReplEngine {

	/** Indicator to terminate once this Job gets IDLE. */
	private volatile boolean fTerminateOnIdle = true;

	/** Result of last script execution. */
	private ScriptResult fLastExecutionResult = null;

	/**
	 * Constructor. Sets the name for the underlying job.
	 *
	 * @param name
	 *            name of script engine job
	 */
	public AbstractReplScriptEngine(final String name) {
		super(name);
	}

	@Override
	public final void setTerminateOnIdle(final boolean terminate) {
		fTerminateOnIdle = terminate;
		synchronized (this) {
			notifyAll();
		}
	}

	@Override
	public boolean getTerminateOnIdle() {
		return fTerminateOnIdle;
	}

	/**
	 * Get termination status of the interpreter. A terminated interpreter cannot be restarted.
	 *
	 * @return true if interpreter is terminated.
	 */
	@Override
	protected boolean isTerminated() {
		return fTerminateOnIdle && isIdle();
	}

	/**
	 * Get idle status of the interpreter. The interpreter is IDLE if there are no pending execution requests and the interpreter is not terminated.
	 *
	 * @return true if interpreter is IDLE
	 */
	@Override
	public boolean isIdle() {
		return super.isTerminated();
	}

	@Override
	public void terminate() {
		setTerminateOnIdle(true);

		super.terminate();
	}

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

		for (final Entry<String, Object> entry : getVariables().entrySet()) {
			if (acceptVariable(entry.getValue())) {
				final EaseDebugVariable variable = createVariable(entry.getKey(), entry.getValue());
				result.add(variable);
			}
		}

		return result;
	}

	protected boolean acceptVariable(Object value) {
		return true;
	}

	protected Collection<EaseDebugVariable> getDefinedVariables(Object scope) {
		return null;
	}

	protected EaseDebugVariable createVariable(String name, Object value) {
		final String referenceType = getTypeName(value);
		final EaseDebugVariable variable = new EaseDebugVariable(name, value, referenceType);

		// TODO find nicer approach to set type
		if ("Java Object".equals(referenceType))
			variable.setType(Type.JAVA_OBJECT);

		else
			variable.getValue().setVariables(getDefinedVariables(value));

		return variable;
	}

	protected String getTypeName(Object object) {
		switch (getType(object)) {
		case NATIVE_ARRAY:
			String languageName = getDescription().getSupportedScriptTypes().get(0).getName();
			return languageName + " Array";

		case NATIVE_OBJECT:
			languageName = getDescription().getSupportedScriptTypes().get(0).getName();
			return languageName + " Object";

		case NATIVE:
			languageName = getDescription().getSupportedScriptTypes().get(0).getName();
			return "Generic " + languageName;

		case JAVA_OBJECT:
			return "Java Object";

		case JAVA_PRIMITIVE:
			if (object instanceof Integer)
				return "int";

			if (object instanceof Byte)
				return "byte";

			if (object instanceof Short)
				return "short";

			if (object instanceof Boolean)
				return "boolean";

			if (object instanceof Character)
				return "char";

			if (object instanceof Long)
				return "long";

			if (object instanceof Double)
				return "double";

			if (object instanceof Float)
				return "float";

			// fall through

		default:
			return "";
		}
	}

	@Override
	public ScriptObjectType getType(Object object) {
		if (object != null) {
			if ((object instanceof Integer) || (object instanceof Byte) || (object instanceof Short) || (object instanceof Boolean)
					|| (object instanceof Character) || (object instanceof Long) || (object instanceof Double) || (object instanceof Float))
				return ScriptObjectType.JAVA_PRIMITIVE;

			if (ScriptResult.VOID.equals(object))
				return ScriptObjectType.VOID;

			return ScriptObjectType.JAVA_OBJECT;

		} else
			return ScriptObjectType.NULL;
	}

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

		if (object != null)
			return object.toString();

		return "null";
	}

	protected final String buildArrayString(List<Object> elements) {
		final StringBuilder output = new StringBuilder("[");

		for (final Object element : elements)
			output.append(", ").append(toString(element));

		output.append(']');

		if (output.length() > 4)
			output.delete(1, 3);

		return output.toString();
	}

	protected final String buildObjectString(Map<String, Object> elements) {
		final StringBuilder output = new StringBuilder("{");

		for (final Entry<String, Object> entry : elements.entrySet())
			output.append(", ").append(entry.getKey()).append(": ").append(toString(entry.getValue()));

		output.append('}');

		if (output.length() > 4)
			output.delete(1, 3);

		return output.toString();
	}

	@Override
	protected void notifyExecutionListeners(Script script, int status) {
		if (IExecutionListener.SCRIPT_END == status)
			fLastExecutionResult = script.getResult();

		super.notifyExecutionListeners(script, status);
	}

	@Override
	public EaseDebugVariable getLastExecutionResult() {
		if (fLastExecutionResult != null) {
			if (ScriptResult.VOID.equals(fLastExecutionResult.getResult())) {
				return new EaseDebugLastExecutionResult("no method return value", ScriptResult.VOID, "");

			} else if (fLastExecutionResult.hasException()) {
				return new EaseDebugLastExecutionResult("script exception", fLastExecutionResult.getException());

			} else {
				final EaseDebugVariable variable = createVariable("script returned", fLastExecutionResult.getResult());
				return new EaseDebugLastExecutionResult(variable);
			}
		} else
			return new EaseDebugLastExecutionResult("no method return value", null, "");
	}

	@Override
	protected void teardownEngine() throws ScriptEngineException {
		fLastExecutionResult = null;
	}
}
