/*******************************************************************************
 * 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.ui.launching;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationType;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.core.Launch;
import org.eclipse.debug.core.model.ISourceLocator;
import org.eclipse.ease.AbstractScriptEngine;
import org.eclipse.ease.IDebugEngine;
import org.eclipse.ease.IExecutionListener;
import org.eclipse.ease.IReplEngine;
import org.eclipse.ease.IScriptEngine;
import org.eclipse.ease.Script;
import org.eclipse.ease.service.EngineDescription;
import org.eclipse.ease.service.IScriptService;
import org.eclipse.ease.service.ScriptType;
import org.eclipse.ease.tools.ResourceTools;
import org.eclipse.ease.tools.RunnableWithResult;
import org.eclipse.ease.tools.StringTools;
import org.eclipse.ease.ui.console.ScriptConsole;
import org.eclipse.ease.ui.tools.AbstractLaunchDelegate;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.PlatformUI;

/**
 * Quick launcher for EASE script files.
 */
public class EaseLaunchDelegate extends AbstractLaunchDelegate {

	private class EASELaunch extends Launch implements IExecutionListener {

		private boolean fIsTerminated = false;

		/**
		 * Constructs a launch with the specified attributes.
		 *
		 * @param launchConfiguration
		 *            the configuration that was launched
		 * @param mode
		 *            the mode of this launch - run or debug (constants defined by <code>ILaunchManager</code>)
		 * @param locator
		 *            the source locator to use for this debug session, or <code>null</code> if not supported
		 */
		public EASELaunch(ILaunchConfiguration launchConfiguration, String mode, ISourceLocator locator) {
			super(launchConfiguration, mode, locator);
		}

		@Override
		public boolean isTerminated() {
			return fIsTerminated || super.isTerminated();
		}

		@Override
		public void notify(IScriptEngine engine, Script script, int status) {
			if (IExecutionListener.ENGINE_END == status) {
				fIsTerminated = true;
				if (DebugPlugin.getDefault() != null) {
					fireTerminate();

					// remove launch when it was triggered in RUN node
					if (ILaunchManager.RUN_MODE.equals(getLaunchMode()))
						getLaunchManager().removeLaunch(this);
				}
			}
		}
	}

	private static final String LAUNCH_CONFIGURATION_ID = "org.eclipse.ease.launchConfigurationType";

	@Override
	public void launch(final ILaunchConfiguration configuration, final String mode, final ILaunch launch, final IProgressMonitor monitor) throws CoreException {

		final String fileLocation = getFileLocation(configuration);
		final Object resource = ResourceTools.resolve(fileLocation);

		if (ResourceTools.isFile(resource)) {

			// create engine
			final String engineID = configuration.getAttribute(LaunchConstants.SCRIPT_ENGINE, "");
			final IScriptService scriptService = PlatformUI.getWorkbench().getService(IScriptService.class);
			EngineDescription engineDescription = scriptService.getEngineByID(engineID);
			if ((ILaunchManager.DEBUG_MODE.equals(mode)) && (!engineDescription.supportsDebugging())) {
				// we are trying to debug using an engine that does not support debugging
				engineDescription = null;

				// try to find an engine that supports debugging
				final ScriptType scriptType = scriptService.getScriptType(ResourceTools.toAbsoluteLocation(resource, null));
				if (scriptType != null) {
					final List<EngineDescription> engines = scriptService.getEngines(scriptType.getName());
					for (final EngineDescription description : engines) {
						if (description.supportsDebugging()) {
							// matching debug engine found
							engineDescription = description;
							break;
						}
					}
				}

				if (engineDescription != null) {
					// ask user if he wants to change the engine: once, permanently or not
					final RunnableWithResult<Boolean> runnable = new RunnableWithResult<Boolean>() {
						@Override
						public Boolean runWithTry() throws Throwable {
							return MessageDialog.openConfirm(Display.getDefault().getActiveShell(), "Configuration change needed",
									"The currently selected script engine does not support debugging. However an alternative engine is available. Do you want to debug your script using that alternative engine?");
						}
					};
					Display.getDefault().syncExec(runnable);

					if (!runnable.getResult())
						// user does not want to switch engine
						return;

				} else {
					// giving up
					Display.getDefault().asyncExec(() -> MessageDialog.openError(Display.getDefault().getActiveShell(), "Launch error",
							"No debug engine available for \"" + resource + "\""));
					return;
				}
			}

			final IScriptEngine engine = engineDescription.createEngine();
			if (engine instanceof IReplEngine)
				((IReplEngine) engine).setTerminateOnIdle(true);

			if (engine instanceof AbstractScriptEngine)
				((AbstractScriptEngine) engine).setLaunch(launch);

			// initialize console
			final ScriptConsole console = ScriptConsole.create(engine.getName() + ": " + resource, engine);
			engine.setOutputStream(console.getOutputStream());
			engine.setErrorStream(console.getErrorStream());
			engine.setInputStream(console.getInputStream());

			// setup debugger
			if (ILaunchManager.DEBUG_MODE.equals(mode))
				setupDebugger(engine, configuration, launch);

			// register libraries
			final Collection<String> libraries = LaunchConstants.getLibraries(configuration);
			for (final String libraryPath : libraries) {
				try {
					engine.registerJar(new URL(libraryPath));
				} catch (final MalformedURLException e) {
					// malformed URL
					Display.getDefault().asyncExec(() -> MessageDialog.openError(Display.getDefault().getActiveShell(), "Launch error",
							"Invalid URL for the library \"" + libraryPath + "\""));
					return;
				}
			}

			// set startup parameters
			final String parameterString = configuration.getAttribute(LaunchConstants.STARTUP_PARAMETERS, "").trim();
			final String[] parameters = StringTools.parseArguments(parameterString);

			engine.setVariable("argv", parameters);

			// execute resource
			engine.executeAsync(resource);

			// start engine
			engine.schedule();

			// let launch know when engine terminates
			if (launch instanceof IExecutionListener)
				engine.addExecutionListener((IExecutionListener) launch);

		} else {
			Display.getDefault().asyncExec(
					() -> MessageDialog.openError(Display.getDefault().getActiveShell(), "Launch error", "File could not be found: \"" + fileLocation + "\""));
		}
	}

	@Override
	protected ILaunchConfiguration createLaunchConfiguration(final IResource file, final String mode) throws CoreException {
		final ILaunchManager manager = DebugPlugin.getDefault().getLaunchManager();
		final ILaunchConfigurationType type = manager.getLaunchConfigurationType(LAUNCH_CONFIGURATION_ID);

		final ILaunchConfigurationWorkingCopy configuration = type.newInstance(null, file.getName());
		configuration.setAttribute(LaunchConstants.FILE_LOCATION, ResourceTools.toAbsoluteLocation(file, null));

		// find a valid engine
		final IScriptService scriptService = PlatformUI.getWorkbench().getService(IScriptService.class);
		final ScriptType scriptType = scriptService.getScriptType(ResourceTools.toAbsoluteLocation(file, null));
		final Collection<EngineDescription> engines;
		if (scriptType == null) {
			engines = Collections.emptyList();
		} else {
			engines = scriptType.getEngines();
		}
		if (engines.isEmpty())
			// TODO use a better way to bail out and use the direct file launch
			throw new CoreException(Status.CANCEL_STATUS);

		configuration.setAttribute(LaunchConstants.SCRIPT_ENGINE, engines.iterator().next().getID());

		// by default a debug configuration should suspend on script startup
		if (ILaunchManager.DEBUG_MODE.equals(mode))
			configuration.setAttribute(LaunchConstants.SUSPEND_ON_STARTUP, true);

		// save and return new configuration
		configuration.doSave();

		return configuration;
	}

	@Override
	protected String getFileLocation(final ILaunchConfiguration configuration) throws CoreException {
		return configuration.getAttribute(LaunchConstants.FILE_LOCATION, "");
	}

	@Override
	protected String getLaunchConfigurationId() {
		return LAUNCH_CONFIGURATION_ID;
	}

	@Override
	public ILaunch getLaunch(ILaunchConfiguration configuration, String mode) throws CoreException {
		return new EASELaunch(configuration, mode, null);
	}

	private void setupDebugger(final IScriptEngine engine, final ILaunchConfiguration configuration, final ILaunch launch) {
		if (engine instanceof IDebugEngine) {
			((IDebugEngine) engine).setupDebugger(launch, getSuspendOnStartupValue(configuration), getSuspendOnScriptLoadValue(configuration),
					getDisplayDynamicCodeValue(configuration));
		}
	}

	public static boolean getSuspendOnStartupValue(ILaunchConfiguration configuration) {
		try {
			return configuration.getAttribute(LaunchConstants.SUSPEND_ON_STARTUP, false);
		} catch (final CoreException e) {
		}

		return false;
	}

	public static boolean getSuspendOnScriptLoadValue(ILaunchConfiguration configuration) {
		try {
			return configuration.getAttribute(LaunchConstants.SUSPEND_ON_SCRIPT_LOAD, false);
		} catch (final CoreException e) {
		}

		return false;
	}

	public static boolean getDisplayDynamicCodeValue(ILaunchConfiguration configuration) {
		try {
			return configuration.getAttribute(LaunchConstants.DISPLAY_DYNAMIC_CODE, false);
		} catch (final CoreException e) {
		}

		return false;
	}
}
