/*******************************************************************************
 * 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 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.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IProgressMonitorWithBlocking;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.ease.ISecurityCheck.ActionType;
import org.eclipse.ease.debugging.EaseDebugFrame;
import org.eclipse.ease.debugging.IScriptDebugFrame;
import org.eclipse.ease.debugging.ScriptStackTrace;
import org.eclipse.ease.security.ScriptUIAccess;
import org.eclipse.ease.service.EngineDescription;
import org.eclipse.ease.tools.ListenerList;
import org.eclipse.ease.tools.ResourceTools;
import org.eclipse.ui.internal.progress.ProgressManager.JobMonitor;
import org.osgi.framework.Version;

/**
 * Base implementation for a script engine. Handles Job implementation of script engine, adding script code for execution, module loading support and a basic
 * online help system.
 */
public abstract class AbstractScriptEngine extends Job implements IScriptEngine {

	/**
	 * Get the current script engine. Works only if executed from the script engine thread.
	 *
	 * @return script engine or <code>null</code>
	 */
	public static IScriptEngine getCurrentScriptEngine() {
		if (Job.getJobManager().currentJob() instanceof IScriptEngine)
			return (IScriptEngine) Job.getJobManager().currentJob();

		return null;
	}

	/**
	 * Get the beautified name of a file to be set as part of the job title.
	 *
	 * @param file
	 *            executed file
	 * @return beautified name or <code>null</code>
	 */
	private static String getFilename(Object file) {
		if (file instanceof IFile) {
			return ResourceTools.toAbsoluteLocation(file, null);
		} else if (file instanceof File) {
			return ResourceTools.toAbsoluteLocation(file, null);
		} else {
			return null;
		}
	}

	/** List of code junks to be executed. */
	private final List<Script> fScheduledScripts = Collections.synchronizedList(new ArrayList<Script>());

	private final ListenerList<IExecutionListener> fExecutionListeners = new ListenerList<>();

	private PrintStream fOutputStream = null;

	private PrintStream fErrorStream = null;

	private InputStream fInputStream = null;

	private final ScriptStackTrace fStackTrace = new ScriptStackTrace();

	private EngineDescription fDescription;

	private boolean fSetupDone = false;

	/** Variables tried to set before engine was started. */
	private final Map<String, Object> fBufferedVariables = new HashMap<>();

	private boolean fCloseStreamsOnTerminate;

	/** Registered security checks for engine actions. */
	private final HashMap<ActionType, List<ISecurityCheck>> fSecurityChecks = new HashMap<>();

	private Object fExecutionRootFile;;

	/** Launch associated with this engine. */
	private ILaunch fLaunch = null;

	private IProgressMonitor fMonitor;

	/**
	 * Constructor. Sets the name for the underlying job.
	 *
	 * @param name
	 *            name of script engine job
	 */
	public AbstractScriptEngine(final String name) {
		super("[EASE " + name + " Engine]");

		// by default an engine shall be visible to the user. If the engine
		setSystem(false);
	}

	@Override
	public EngineDescription getDescription() {
		return fDescription;
	}

	@Override
	public final ScriptResult executeAsync(final Object content) {
		final Script script = (content instanceof Script) ? (Script) content : new Script(content);
		fScheduledScripts.add(script);

		synchronized (this) {
			notifyAll();
		}

		return script.getResult();
	}

	@Override
	public final ScriptResult executeSync(final Object content) throws InterruptedException {

		// we need to schedule the script first or the engine might finish before we can schedule the script
		final ScriptResult result = executeAsync(content);

		if (getState() == NONE)
			// automatically schedule engine as it is not started yet
			schedule();

		result.waitForResult();

		return result;
	}

	@Override
	public final Object inject(final Object content) {
		return internalInject(content, false);
	}

	@Override
	public final Object injectUI(final Object content) {
		return internalInject(content, true);
	}

	private final Object internalInject(final Object content, final boolean uiThread) {
		// injected code shall not trigger a new event, therefore notifyListerners needs to be false
		ScriptResult result;
		if (content instanceof Script)
			result = inject((Script) content, false, uiThread);
		else
			result = inject(new Script(content), false, uiThread);

		if (result.hasException()) {
			// re-throw previous exception

			if (result.getException() instanceof RuntimeException)
				throw (RuntimeException) result.getException();

			throw new RuntimeException(result.getException().getMessage(), result.getException());
		}

		return result.getResult();
	}

	/**
	 * Inject script code to the script engine. Injected code is processed synchronous by the current thread unless <i>uiThread</i> is set to <code>true</code>.
	 * Nevertheless this is a blocking call.
	 *
	 * @param script
	 *            script to be executed
	 * @param notifyListeners
	 *            <code>true</code> when listeners should be informed of code fragment
	 * @param uiThread
	 *            when set to <code>true</code> run injected code in UI thread
	 * @return script execution result
	 */
	private ScriptResult inject(final Script script, final boolean notifyListeners, final boolean uiThread) {

		try {
			Logger.trace(Activator.PLUGIN_ID, TRACE_SCRIPT_ENGINE, "Executing script (" + script.getTitle() + "):", script.getCode());
			final String filename = getFilename(script.getFile());
			fStackTrace.add(0, new EaseDebugFrame(script, 0, IScriptDebugFrame.TYPE_FILE, filename));
			updateJobName(filename);

			// apply security checks
			final List<ISecurityCheck> securityChecks = fSecurityChecks.get(ActionType.INJECT_CODE);
			if (securityChecks != null) {
				for (final ISecurityCheck check : securityChecks) {
					if (!check.doIt(ActionType.INJECT_CODE, script, uiThread))
						throw new ScriptEngineException("Security check failed: " + check.toString());
				}
			}

			// execution
			if (notifyListeners)
				notifyExecutionListeners(script, IExecutionListener.SCRIPT_START);
			else
				notifyExecutionListeners(script, IExecutionListener.SCRIPT_INJECTION_START);

			script.setResult(execute(script, script.getFile(), fStackTrace.get(0).getName(), uiThread));

		} catch (final BreakException e) {
			script.setResult(e.getCondition());

		} catch (final Throwable e) {
			// only do the printing if this is the last script on the stack
			// otherwise we will print multiple times for each rethrow
			if (fStackTrace.size() <= 1)
				e.printStackTrace(getErrorStream());

			script.setException(e);

		} finally {
			if (notifyListeners)
				notifyExecutionListeners(script, IExecutionListener.SCRIPT_END);
			else
				notifyExecutionListeners(script, IExecutionListener.SCRIPT_INJECTION_END);

			if (!fStackTrace.isEmpty())
				fStackTrace.remove(0);
		}

		return script.getResult();
	}

	private void updateJobName(String filename) {
		if (filename != null) {
			String baseName = getName();
			if (baseName.contains("]"))
				baseName = baseName.substring(0, baseName.indexOf(']') + 1);

			setName(baseName + " " + filename);
		}
	}

	@Override
	protected IStatus run(final IProgressMonitor monitor) {
		fMonitor = monitor;

		addStopButtonMonitor();

		IStatus returnStatus = setupRun();
		if (Status.OK_STATUS.equals(returnStatus)) {
			// main loop
			while (!shallTerminate()) {

				// execute code
				if (!fScheduledScripts.isEmpty()) {
					final Script piece = fScheduledScripts.remove(0);
					inject(piece, true, false);

				} else {
					synchronized (this) {
						try {
							Logger.trace(Activator.PLUGIN_ID, TRACE_SCRIPT_ENGINE, "Engine idle: " + getName());
							wait();
						} catch (final InterruptedException e) {
						}
					}
				}
			}
		}

		if (getMonitor().isCanceled())
			returnStatus = Status.CANCEL_STATUS;

		return cleanupRun(returnStatus);
	}

	private IStatus setupRun() {
		Logger.trace(Activator.PLUGIN_ID, TRACE_SCRIPT_ENGINE, "Engine started: " + getName());

		addSecurityCheck(ActionType.INJECT_CODE, ScriptUIAccess.getInstance());

		try {
			setupEngine();
			fSetupDone = true;

			// engine is initialized, set buffered variables
			for (final Entry<String, Object> entry : fBufferedVariables.entrySet()) {
				setVariable(entry.getKey(), entry.getValue());
			}

			fBufferedVariables.clear();

			// setup new trace
			fStackTrace.clear();

			notifyExecutionListeners(null, IExecutionListener.ENGINE_START);

		} catch (final ScriptEngineException e) {
			return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Could not setup script engine", e);
		}

		return Status.OK_STATUS;
	}

	private IStatus cleanupRun(IStatus returnStatus) {

		// discard pending code pieces
		synchronized (fScheduledScripts) {
			for (final Script script : fScheduledScripts)
				script.setException(new ScriptExecutionException("Engine got terminated"));
		}

		fScheduledScripts.clear();

		notifyExecutionListeners(null, IExecutionListener.ENGINE_END);

		try {
			teardownEngine();
		} catch (final ScriptEngineException e) {
			if (returnStatus.getSeverity() < IStatus.ERROR) {
				// We were almost all OK (or just warnings/infos) but then we failed at shutdown
				// Note we don't override a CANCEL
				returnStatus = new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Could not teardown script engine", e);
			}
		} finally {
			synchronized (this) {
				notifyAll();
			}

			closeStreams();

			Logger.trace(Activator.PLUGIN_ID, TRACE_SCRIPT_ENGINE, "Engine terminated: " + getName());

			fMonitor.done();
			fMonitor = null;
		}

		return returnStatus;
	}

	/**
	 * Add monitor to detect clicks on the stop button in the Progress view.
	 */
	private void addStopButtonMonitor() {
		final Version workbenchBundleVersion = Platform.getBundle("org.eclipse.ui.workbench").getVersion();
		if (workbenchBundleVersion.compareTo(Version.valueOf("3.120.0")) >= 0) {
			// JobMonitor changed its API from
			// 		addProgressListener(IProgressMonitor)
			// to
			// 		addProgressListener(IProgressMonitorWithBlocking)
			// in 2020.09
			if (fMonitor instanceof JobMonitor)
				((JobMonitor) fMonitor).addProgressListener((IProgressMonitor) new ScriptEngineMonitor());
		} else if (workbenchBundleVersion.compareTo(Version.valueOf("3.110.1")) >= 0) {
			// JobMonitor is a private class up to 3.110.1 (Eclipse Oxygen)
			// this functionality improves usability, but is not essential to scripting
			if (fMonitor instanceof JobMonitor)
				((JobMonitor) fMonitor).addProgressListener((IProgressMonitorWithBlocking) new ScriptEngineMonitor());
		}
	}

	/**
	 * Evaluate if the engine shall terminate.
	 *
	 * @return <code>true</code> when termination is requested or there is no more work to be done
	 */
	protected boolean shallTerminate() {
		return getMonitor().isCanceled() || fScheduledScripts.isEmpty();
	}

	@Override
	public void terminate() {

		final IProgressMonitor monitor = getMonitor();
		if ((monitor != null) && (!monitor.isCanceled()))
			monitor.setCanceled(true);

		terminateCurrent();

		synchronized (this) {
			notify();
		}
	}

	/**
	 * Check engine for cancellation request and terminate if indicated by the monitor.
	 */
	public void checkForCancellation() {
		final IProgressMonitor monitor = getMonitor();
		if ((monitor != null) && (monitor.isCanceled())) {
			if (Thread.currentThread().equals(getThread()))
				throw new ScriptExecutionException("Engine got terminated");
		}
	}

	@Override
	public boolean isFinished() {
		// setup was done, hence we were started
		return (Job.NONE == getState()) && fSetupDone;
	}

	@Override
	public void joinEngine() throws InterruptedException {
		if (!Thread.currentThread().equals(getThread())) {
			// we cannot join our own thread

			synchronized (this) {
				while (!isFinished())
					wait(1000);
			}
		}
	}

	@Override
	public void joinEngine(final long timeout) throws InterruptedException {
		if (!Thread.currentThread().equals(getThread())) {
			// we cannot join our own thread

			synchronized (this) {
				if (!isFinished())
					wait(timeout);
			}
		}
	}

	@Override
	public IProgressMonitor getMonitor() {
		return fMonitor;
	}

	private void closeStreams() {
		if (fCloseStreamsOnTerminate) {
			// gracefully close I/O streams
			try {
				if ((getInputStream() != null) && (!System.in.equals(getInputStream())))
					getInputStream().close();
			} catch (final IOException e) {
			}
			try {
				if ((getOutputStream() != null) && (!System.out.equals(getOutputStream())))
					getOutputStream().close();
			} catch (final Exception e) {
			}
			try {
				if ((getErrorStream() != null) && (!System.err.equals(getErrorStream())))
					getErrorStream().close();
			} catch (final Exception e) {
			}
		}

		fOutputStream = null;
		fErrorStream = null;
		fInputStream = null;
	}

	@Override
	public void setCloseStreamsOnTerminate(final boolean closeStreams) {
		fCloseStreamsOnTerminate = closeStreams;
	}

	@Override
	public PrintStream getOutputStream() {
		return (fOutputStream != null) ? fOutputStream : System.out;
	}

	@Override
	public void setOutputStream(final OutputStream outputStream) {
		if (outputStream instanceof PrintStream)
			fOutputStream = (PrintStream) outputStream;

		else if (outputStream != null)
			fOutputStream = new PrintStream(outputStream);
		else
			fOutputStream = null;
	}

	@Override
	public InputStream getInputStream() {
		return (fInputStream != null) ? fInputStream : System.in;
	}

	@Override
	public void setInputStream(final InputStream inputStream) {
		fInputStream = inputStream;
	}

	@Override
	public PrintStream getErrorStream() {
		return (fErrorStream != null) ? fErrorStream : System.err;
	}

	@Override
	public void setErrorStream(final OutputStream errorStream) {
		if (errorStream instanceof PrintStream)
			fErrorStream = (PrintStream) errorStream;

		else if (errorStream != null)
			fErrorStream = new PrintStream(errorStream);
		else
			fErrorStream = null;
	}

	@Override
	public void addExecutionListener(final IExecutionListener listener) {
		fExecutionListeners.add(listener);
	}

	@Override
	public void removeExecutionListener(final IExecutionListener listener) {
		fExecutionListeners.remove(listener);
	}

	protected void notifyExecutionListeners(final Script script, final int status) {
		for (final Object listener : fExecutionListeners.getListeners())
			((IExecutionListener) listener).notify(this, script, status);
	}

	public ScriptStackTrace getStackTrace() {
		return fStackTrace;
	}

	@Override
	public Object getExecutedFile() {
		for (final IScriptDebugFrame trace : getStackTrace()) {
			if (trace.getType() == IScriptDebugFrame.TYPE_FILE) {
				if (trace.getScript() != null) {
					final Object file = trace.getScript().getFile();
					if (file != null)
						return file;
				}
			}
		}

		return fExecutionRootFile;
	}

	public void setExecutionRootFile(Object executionRootFile) {
		fExecutionRootFile = executionRootFile;
	}

	public void setEngineDescription(final EngineDescription description) {
		fDescription = description;
	}

	@Override
	public void setVariable(final String name, final Object content) {
		if (fSetupDone)
			internalSetVariable(name, content);

		else
			fBufferedVariables.put(name, content);
	}

	@Override
	public Object getVariable(final String name) {
		if (fSetupDone)
			return internalGetVariable(name);

		return fBufferedVariables.get(name);
	}

	@Override
	public boolean hasVariable(final String name) {
		if (fSetupDone)
			return internalHasVariable(name);

		return fBufferedVariables.containsKey(name);
	}

	@Override
	public Map<String, Object> getVariables() {
		if (fSetupDone)
			return internalGetVariables();

		return Collections.unmodifiableMap(fBufferedVariables);
	}

	/**
	 * Split a string with comma separated arguments.
	 *
	 * @param arguments
	 *            comma separated arguments
	 * @return trimmed list of arguments
	 */
	public static final String[] extractArguments(final String arguments) {
		final ArrayList<String> args = new ArrayList<>();
		if (arguments != null) {

			final String[] tokens = arguments.split(",");
			for (final String token : tokens) {
				if (!token.trim().isEmpty())
					args.add(token.trim());
			}
		}

		return args.toArray(new String[args.size()]);
	}

	@Override
	public void addSecurityCheck(ActionType type, ISecurityCheck check) {
		if (!fSecurityChecks.containsKey(type))
			fSecurityChecks.put(type, new ArrayList<ISecurityCheck>());

		if (!fSecurityChecks.get(type).contains(check))
			fSecurityChecks.get(type).add(check);
	}

	@Override
	public void removeSecurityCheck(ISecurityCheck check) {
		for (final List<ISecurityCheck> entry : fSecurityChecks.values()) {
			entry.remove(check);
		}
	}

	protected List<Script> getScheduledScripts() {
		return fScheduledScripts;
	}

	public void setLaunch(ILaunch launch) {
		fLaunch = launch;
	}

	@Override
	public ILaunch getLaunch() {
		return fLaunch;
	}

	/**
	 * Internal version of {@link #getVariable(String)}. Only called after script engine was initialized successfully.
	 */
	protected abstract Object internalGetVariable(String name);

	/**
	 * Internal version of {@link #getVariables()}. Only called after script engine was initialized successfully.
	 */
	protected abstract Map<String, Object> internalGetVariables();

	/**
	 * Internal version of {@link #hasVariable(String)}. Only called after script engine was initialized successfully.
	 */
	protected abstract boolean internalHasVariable(String name);

	/**
	 * Internal version of {@link #setVariable(String, Object)}. Only called after script engine was initialized successfully.
	 */
	protected abstract void internalSetVariable(String name, Object content);

	/**
	 * Setup method for script engine. Run directly after the engine is activated.
	 *
	 * Unresolvable errors should be indicated by throwing a ScriptEngineException with details as to what went wrong.
	 */
	protected abstract void setupEngine() throws ScriptEngineException;

	/**
	 * Teardown engine. Called immediately before the engine terminates. This method is called even when {@link #setupEngine()} fails.
	 */
	protected abstract void teardownEngine() throws ScriptEngineException;

	/**
	 * Execute script code.
	 *
	 * @param fileName
	 *            name of file executed
	 * @param uiThread
	 * @param reader
	 *            reader for script data to be executed
	 * @param uiThread
	 *            when set to <code>true</code> run code in UI thread
	 * @return execution result
	 * @throws Throwable
	 *             any exception thrown during script execution
	 */
	protected abstract Object execute(Script script, Object reference, String fileName, boolean uiThread) throws Throwable;

	/**
	 * Simple monitor to forward cancellation requests to the script engine.
	 */
	private class ScriptEngineMonitor extends NullProgressMonitor implements IProgressMonitorWithBlocking {

		@Override
		public void setCanceled(boolean cancelled) {
			super.setCanceled(cancelled);

			if (isCanceled())
				terminate();
		}

		@Override
		public void setBlocked(IStatus reason) {
			// nothing to do
		}

		@Override
		public void clearBlocked() {
			// nothing to do
		}
	}
}
