/*******************************************************************************
 * Copyright (c) 2000, 2016 IBM Corporation and others.
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 * 
 * SPDX-License-Identifier: EPL-2.0
 *
 *******************************************************************************/
package org.eclipse.dltk.launching;

import java.net.URI;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.AssertionFailedException;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.core.variables.IStringVariableManager;
import org.eclipse.core.variables.VariablesPlugin;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.core.IStatusHandler;
import org.eclipse.debug.core.Launch;
import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.debug.core.model.LaunchConfigurationDelegate;
import org.eclipse.dltk.core.DLTKCore;
import org.eclipse.dltk.core.IScriptModelMarker;
import org.eclipse.dltk.core.IScriptProject;
import org.eclipse.dltk.core.ISourceModule;
import org.eclipse.dltk.core.environment.EnvironmentManager;
import org.eclipse.dltk.core.environment.EnvironmentPathUtils;
import org.eclipse.dltk.core.environment.IEnvironment;
import org.eclipse.dltk.core.environment.IExecutionEnvironment;
import org.eclipse.dltk.core.environment.IFileHandle;
import org.eclipse.dltk.debug.core.DLTKDebugLaunchConstants;
import org.eclipse.dltk.internal.launching.DLTKLaunchingPlugin;
import org.eclipse.dltk.internal.launching.InterpreterRuntimeBuildpathEntryResolver;
import org.eclipse.dltk.launching.debug.DebuggingEngineManager;
import org.eclipse.osgi.util.NLS;

import com.ibm.icu.text.MessageFormat;

/**
 * Abstract implementation of a Script launch configuration delegate. Provides
 * convenience methods for accessing and verifying launch configuration
 * attributes.
 * <p>
 * Clients implementing Script launch configuration delegates should subclass
 * this class.
 * </p>
 */
public abstract class AbstractScriptLaunchConfigurationDelegate
		extends LaunchConfigurationDelegate {

	/**
	 * A list of prerequisite projects ordered by their build order.
	 */
	private IProject[] fOrderedProjects;

	/**
	 * Convenience method to get the launch manager.
	 *
	 * @return the launch manager
	 */
	protected ILaunchManager getLaunchManager() {
		return DebugPlugin.getDefault().getLaunchManager();
	}

	/**
	 * Throws a core exception with an error status object built from the given
	 * message, lower level exception, and error code.
	 *
	 * @param message
	 *            the status message
	 * @param exception
	 *            lower level exception associated with the error, or
	 *            <code>null</code> if none
	 * @param code
	 *            error code
	 * @throws CoreException
	 *             the "abort" core exception
	 * @since 3.0
	 */
	protected CoreException abort(String message, Throwable exception, int code)
			throws CoreException {
		throw new CoreException(new Status(IStatus.ERROR,
				DLTKLaunchingPlugin.PLUGIN_ID, code, message, exception));
	}

	/**
	 * @since 3.0
	 */
	protected CoreException abort(String message, Throwable exception)
			throws CoreException {
		throw new CoreException(
				new Status(IStatus.ERROR, DLTKLaunchingPlugin.PLUGIN_ID,
						ScriptLaunchConfigurationConstants.ERR_INTERNAL_ERROR,
						message, exception));
	}

	/**
	 * Returns the Interpreter install specified by the given launch
	 * configuration, or <code>null</code> if none.
	 *
	 * @param configuration
	 *            launch configuration
	 * @return the Interpreter install specified by the given launch
	 *         configuration, or <code>null</code> if none
	 * @exception CoreException
	 *                if unable to retrieve the attribute
	 */
	public IInterpreterInstall getInterpreterInstall(
			ILaunchConfiguration configuration) throws CoreException {
		return ScriptRuntime.computeInterpreterInstall(configuration);
	}

	/**
	 * Verifies the Interpreter install specified by the given launch
	 * configuration exists and returns the Interpreter install.
	 *
	 * @param configuration
	 *            launch configuration
	 * @return the Interpreter install specified by the given launch
	 *         configuration
	 * @exception CoreException
	 *                if unable to retrieve the attribute, the attribute is
	 *                unspecified, or if the home location is unspecified or
	 *                does not exist
	 */
	public IInterpreterInstall verifyInterpreterInstall(
			ILaunchConfiguration configuration) throws CoreException {
		IInterpreterInstall interpreter = getInterpreterInstall(configuration);
		if (interpreter == null) {
			throw abort(
					LaunchingMessages.AbstractScriptLaunchConfigurationDelegate_The_specified_InterpreterEnvironment_installation_does_not_exist_4,
					null,
					ScriptLaunchConfigurationConstants.ERR_INTERPRETER_INSTALL_DOES_NOT_EXIST);
		}
		IFileHandle location = interpreter.getInstallLocation();
		if (location == null) {
			throw abort(MessageFormat.format(
					LaunchingMessages.AbstractScriptLaunchConfigurationDelegate_InterpreterEnvironment_home_directory_not_specified_for__0__5,
					interpreter.getName()), null,
					ScriptLaunchConfigurationConstants.ERR_INTERPRETER_INSTALL_DOES_NOT_EXIST);
		}
		if (!location.exists()) {
			abort(MessageFormat.format(
					LaunchingMessages.AbstractScriptLaunchConfigurationDelegate_InterpreterEnvironment_home_directory_for__0__does_not_exist___1__6,
					interpreter.getName(), location.toURI().toString()), null,
					ScriptLaunchConfigurationConstants.ERR_INTERPRETER_INSTALL_DOES_NOT_EXIST);
		}
		return interpreter;
	}

	/**
	 * Returns the Interpreter connector identifier specified by the given
	 * launch configuration, or <code>null</code> if none.
	 *
	 * @param configuration
	 *            launch configuration
	 * @return the Interpreter connector identifier specified by the given
	 *         launch configuration, or <code>null</code> if none
	 * @exception CoreException
	 *                if unable to retrieve the attribute
	 */
	public String getDebugConnectorId(ILaunchConfiguration configuration)
			throws CoreException {
		return configuration.getAttribute(
				ScriptLaunchConfigurationConstants.ATTR_DEBUG_CONNECTOR,
				(String) null);
	}

	public String[] getBuildpath(ILaunchConfiguration configuration)
			throws CoreException {
		return getBuildpath(configuration, getScriptEnvironment(configuration));
	}

	/**
	 * Returns the entries that should appear on the user portion of the
	 * buildpath as specified by the given launch configuration, as an array of
	 * resolved strings. The returned array is empty if no buildpath is
	 * specified.
	 *
	 * @param configuration
	 *            launch configuration
	 * @return the buildpath specified by the given launch configuration,
	 *         possibly an empty array
	 * @exception CoreException
	 *                if unable to retrieve the attribute
	 */
	public String[] getBuildpath(ILaunchConfiguration configuration,
			IEnvironment environment) throws CoreException {

		// Get entries
		IRuntimeBuildpathEntry[] entries = ScriptRuntime
				.computeUnresolvedRuntimeBuildpath(configuration);
		entries = ScriptRuntime.resolveRuntimeBuildpath(entries, configuration);

		// Get USER_ENTRY
		List<String> userEntries = new ArrayList<>();
		for (int i = 0; i < entries.length; i++) {
			if (entries[i]
					.getBuildpathProperty() == IRuntimeBuildpathEntry.USER_ENTRY) {
				final IPath path = entries[i].getPath();
				final String userPath;
				if (EnvironmentPathUtils.isFull(path)) {
					userPath = EnvironmentPathUtils.getFile(path).toOSString();
				} else {
					URI uri = entries[i].getLocationURI();
					if (uri != null) {
						final IFileHandle handle = environment.getFile(uri);
						if (handle != null) {
							userPath = handle.toOSString();
						} else {
							userPath = null;
						}
					} else {
						userPath = null;
					}
				}
				if (userPath != null && !userEntries.contains(userPath))
					userEntries.add(userPath);
			}
		}
		return userEntries.toArray(new String[userEntries.size()]);
	}

	/**
	 * Returns entries that should appear on the bootstrap portion of the
	 * buildpath as specified by the given launch configuration, as an array of
	 * resolved strings. The returned array is <code>null</code> if all entries
	 * are standard (i.e. appear by default), or empty to represent an empty
	 * bootpath.
	 *
	 * @param configuration
	 *            launch configuration
	 * @return the bootpath specified by the given launch configuration. An
	 *         empty bootpath is specified by an empty array, and
	 *         <code>null</code> represents a default bootpath.
	 * @exception CoreException
	 *                if unable to retrieve the attribute
	 */
	public String[] getBootpath(ILaunchConfiguration configuration)
			throws CoreException {
		String[][] paths = getBootpathExt(configuration);
		String[] pre = paths[0];
		String[] main = paths[1];
		String[] app = paths[2];
		if (pre == null && main == null && app == null) {
			// default
			return null;
		}
		IRuntimeBuildpathEntry[] entries = ScriptRuntime
				.computeUnresolvedRuntimeBuildpath(configuration);
		entries = ScriptRuntime.resolveRuntimeBuildpath(entries, configuration);
		List<String> bootEntries = new ArrayList<>(entries.length);
		boolean empty = true;
		boolean allStandard = true;
		for (int i = 0; i < entries.length; i++) {
			if (entries[i]
					.getBuildpathProperty() != IRuntimeBuildpathEntry.USER_ENTRY) {
				String location = entries[i].getLocation();
				if (location != null) {
					empty = false;
					bootEntries.add(location);
					allStandard = allStandard && entries[i]
							.getBuildpathProperty() == IRuntimeBuildpathEntry.STANDARD_ENTRY;
				}
			}
		}

		if (empty) {
			return new String[0];
		} else if (allStandard) {
			return null;
		} else {
			return bootEntries.toArray(new String[bootEntries.size()]);
		}
	}

	/**
	 * Returns three sets of entries which represent the boot buildpath
	 * specified in the launch configuration, as an array of three arrays of
	 * resolved strings. The first array represents the buildpath that should be
	 * prepended to the boot buildpath. The second array represents the main
	 * part of the boot buildpath -<code>null</code> represents the default
	 * bootbuildpath. The third array represents the buildpath that should be
	 * appended to the boot buildpath.
	 *
	 * @param configuration
	 *            launch configuration
	 * @return a description of the boot buildpath specified by the given launch
	 *         configuration.
	 * @exception CoreException
	 *                if unable to retrieve the attribute
	 *
	 */
	public String[][] getBootpathExt(ILaunchConfiguration configuration)
			throws CoreException {
		String[][] bootpathInfo = new String[3][];
		IRuntimeBuildpathEntry[] entries = ScriptRuntime
				.computeUnresolvedRuntimeBuildpath(configuration);
		List<IRuntimeBuildpathEntry> bootEntriesPrepend = new ArrayList<>();
		int index = 0;
		IRuntimeBuildpathEntry interpreterEnvironmentEntry = null;
		IScriptProject project = getScriptProject(configuration);
		IEnvironment environment = EnvironmentManager.getEnvironment(project);
		while (interpreterEnvironmentEntry == null && index < entries.length) {
			IRuntimeBuildpathEntry entry = entries[index++];
			if (entry
					.getBuildpathProperty() == IRuntimeBuildpathEntry.BOOTSTRAP_ENTRY
					|| entry.getBuildpathProperty() == IRuntimeBuildpathEntry.STANDARD_ENTRY) {
				if (ScriptRuntime.isInterpreterInstallReference(getLanguageId(),
						environment.getId(), entry)) {
					interpreterEnvironmentEntry = entry;
				} else {
					bootEntriesPrepend.add(entry);
				}
			}
		}
		IRuntimeBuildpathEntry[] bootEntriesPrep = ScriptRuntime
				.resolveRuntimeBuildpath(bootEntriesPrepend.toArray(
						new IRuntimeBuildpathEntry[bootEntriesPrepend.size()]),
						configuration);
		String[] entriesPrep = null;
		if (bootEntriesPrep.length > 0) {
			entriesPrep = new String[bootEntriesPrep.length];
			for (int i = 0; i < bootEntriesPrep.length; i++) {
				entriesPrep[i] = bootEntriesPrep[i].getLocation();
			}
		}
		if (interpreterEnvironmentEntry != null) {
			List<IRuntimeBuildpathEntry> bootEntriesAppend = new ArrayList<>();
			for (; index < entries.length; index++) {
				IRuntimeBuildpathEntry entry = entries[index];
				if (entry
						.getBuildpathProperty() == IRuntimeBuildpathEntry.BOOTSTRAP_ENTRY) {
					bootEntriesAppend.add(entry);
				}
			}
			bootpathInfo[0] = entriesPrep;
			IRuntimeBuildpathEntry[] bootEntriesApp = ScriptRuntime
					.resolveRuntimeBuildpath(bootEntriesAppend.toArray(
							new IRuntimeBuildpathEntry[bootEntriesAppend
									.size()]),
							configuration);
			if (bootEntriesApp.length > 0) {
				bootpathInfo[2] = new String[bootEntriesApp.length];
				for (int i = 0; i < bootEntriesApp.length; i++) {
					bootpathInfo[2][i] = bootEntriesApp[i].getLocation();
				}
			}
			IInterpreterInstall install = getInterpreterInstall(configuration);
			LibraryLocation[] libraryLocations = install.getLibraryLocations();
			if (libraryLocations != null) {
				// determine if explicit bootpath should be used
				// TODO: this test does not tell us if the bootpath entries are
				// different (could still be
				// the same, as a non-bootpath entry on the
				// InterpreterEnvironment may have been removed/added)
				// We really need a way to ask a Interpreter type for its
				// default bootpath library locations and
				// compare that to the resolved entries for the
				// "InterpreterEnvironmentEntry" to see if they
				// are different (requires explicit bootpath)
				if (!InterpreterRuntimeBuildpathEntryResolver.isSameArchives(
						libraryLocations,
						install.getInterpreterInstallType()
								.getDefaultLibraryLocations(
										install.getInstallLocation(),
										install.getEnvironmentVariables(),
										null))) {
					// resolve bootpath entries in InterpreterEnvironment entry
					IRuntimeBuildpathEntry[] bootEntries = null;
					if (interpreterEnvironmentEntry
							.getType() == IRuntimeBuildpathEntry.CONTAINER) {
						IRuntimeBuildpathEntry bootEntry = ScriptRuntime
								.newRuntimeContainerBuildpathEntry(
										interpreterEnvironmentEntry.getPath(),
										IRuntimeBuildpathEntry.BOOTSTRAP_ENTRY,
										getScriptProject(configuration));
						bootEntries = ScriptRuntime
								.resolveRuntimeBuildpathEntry(bootEntry,
										configuration);
					} else {
						bootEntries = ScriptRuntime
								.resolveRuntimeBuildpathEntry(
										interpreterEnvironmentEntry,
										configuration);
					}

					// non-default InterpreterEnvironment libraries - use
					// explicit bootpath only
					String[] bootpath = new String[bootEntriesPrep.length
							+ bootEntries.length + bootEntriesApp.length];
					if (bootEntriesPrep.length > 0) {
						System.arraycopy(bootpathInfo[0], 0, bootpath, 0,
								bootEntriesPrep.length);
					}
					int dest = bootEntriesPrep.length;
					for (int i = 0; i < bootEntries.length; i++) {
						bootpath[dest] = bootEntries[i].getLocation();
						dest++;
					}
					if (bootEntriesApp.length > 0) {
						System.arraycopy(bootpathInfo[2], 0, bootpath, dest,
								bootEntriesApp.length);
					}
					bootpathInfo[0] = null;
					bootpathInfo[1] = bootpath;
					bootpathInfo[2] = null;
				}
			}
		} else {
			if (entriesPrep == null) {
				bootpathInfo[1] = new String[0];
			} else {
				bootpathInfo[1] = entriesPrep;
			}
		}
		return bootpathInfo;
	}

	/**
	 * Returns the Script project specified by the given launch configuration,
	 * or <code>null</code> if none.
	 *
	 * @param configuration
	 *            launch configuration
	 * @return the Script project specified by the given launch configuration,
	 *         or <code>null</code> if none
	 * @exception CoreException
	 *                if unable to retrieve the attribute
	 */
	public static IScriptProject getScriptProject(
			ILaunchConfiguration configuration) throws CoreException {
		String projectName = getScriptProjectName(configuration);
		if (projectName != null) {
			projectName = projectName.trim();
			if (projectName.length() > 0) {
				IProject project = getWorkspaceRoot().getProject(projectName);
				IScriptProject scriptProject = DLTKCore.create(project);
				if (scriptProject != null && scriptProject.exists()) {
					return scriptProject;
				}
			}
		}
		return null;
	}

	public static IProject getProject(ILaunchConfiguration configuration)
			throws CoreException {
		String projectName = getScriptProjectName(configuration);
		if (projectName != null) {
			projectName = projectName.trim();
			if (projectName.length() > 0) {
				IProject project = getWorkspaceRoot().getProject(projectName);
				if (project != null && project.exists()) {
					return project;
				}
			}
		}
		return null;
	}

	private static IWorkspaceRoot getWorkspaceRoot() {
		return ResourcesPlugin.getWorkspace().getRoot();
	}

	/**
	 * Returns the Script project name specified by the given launch
	 * configuration, or <code>null</code> if none.
	 *
	 * @param configuration
	 *            launch configuration
	 * @return the Script project name specified by the given launch
	 *         configuration, or <code>null</code> if none
	 * @exception CoreException
	 *                if unable to retrieve the attribute
	 */
	public static String getScriptProjectName(
			ILaunchConfiguration configuration) throws CoreException {
		return configuration.getAttribute(
				ScriptLaunchConfigurationConstants.ATTR_PROJECT_NAME,
				(String) null);
	}

	/**
	 * Returns the main type name specified by the given launch configuration,
	 * or <code>null</code> if none.
	 *
	 * @param configuration
	 *            launch configuration
	 * @return the main type name specified by the given launch configuration,
	 *         or <code>null</code> if none
	 * @exception CoreException
	 *                if unable to retrieve the attribute
	 */
	public static String getMainScriptName(ILaunchConfiguration configuration)
			throws CoreException {
		String script = configuration.getAttribute(
				ScriptLaunchConfigurationConstants.ATTR_MAIN_SCRIPT_NAME,
				(String) null);
		if (script == null) {
			return null;
		}
		return VariablesPlugin.getDefault().getStringVariableManager()
				.performStringSubstitution(script);
	}

	/**
	 * Returns the program arguments specified by the given launch
	 * configuration, as a string. The returned string is empty if no program
	 * arguments are specified.
	 *
	 * @param configuration
	 *            launch configuration
	 * @return the program arguments specified by the given launch
	 *         configuration, possibly an empty string
	 * @exception CoreException
	 *                if unable to retrieve the attribute
	 */
	public String[] getScriptArguments(ILaunchConfiguration configuration)
			throws CoreException {
		String arguments = configuration.getAttribute(
				ScriptLaunchConfigurationConstants.ATTR_SCRIPT_ARGUMENTS, ""); //$NON-NLS-1$
		String args = VariablesPlugin.getDefault().getStringVariableManager()
				.performStringSubstitution(arguments);

		return DebugPlugin.parseArguments(args);
	}

	/**
	 * Returns the Interpreter arguments specified by the given launch
	 * configuration, as a string. The returned string is empty if no
	 * Interpreter arguments are specified.
	 *
	 * @param configuration
	 *            launch configuration
	 * @return the Interpreter arguments specified by the given launch
	 *         configuration, possibly an empty string
	 * @exception CoreException
	 *                if unable to retrieve the attribute
	 */
	protected final String[] getInterpreterArguments(
			ILaunchConfiguration configuration) throws CoreException {
		String arguments = configuration.getAttribute(
				ScriptLaunchConfigurationConstants.ATTR_INTERPRETER_ARGUMENTS,
				""); //$NON-NLS-1$

		String args = VariablesPlugin.getDefault().getStringVariableManager()
				.performStringSubstitution(arguments);

		return DebugPlugin.parseArguments(args);
	}

	/**
	 * Returns the Map of Interpreter-specific attributes specified by the given
	 * launch configuration, or <code>null</code> if none.
	 *
	 * @param configuration
	 *            launch configuration
	 * @return the <code>Map</code> of Interpreter-specific attributes
	 * @exception CoreException
	 *                if unable to retrieve the attribute
	 */
	public Map<String, String> getInterpreterSpecificAttributesMap(
			ILaunchConfiguration configuration) throws CoreException {
		Map<String, String> map = configuration.getAttribute(
				ScriptLaunchConfigurationConstants.ATTR_INTERPRETER_INSTALL_TYPE_SPECIFIC_ATTRS_MAP,
				(Map<String, String>) null);
		return map;
	}

	/**
	 * Returns the working directory specified by the given launch
	 * configuration, or <code>null</code> if none.
	 *
	 * @param configuration
	 *            launch configuration
	 * @return the working directory specified by the given launch
	 *         configuration, or <code>null</code> if none
	 * @exception CoreException
	 *                if unable to retrieve the attribute
	 */
	public String getWorkingDirectory(ILaunchConfiguration configuration,
			IEnvironment environment) throws CoreException {
		return verifyWorkingDirectory(configuration, environment);
	}

	/**
	 * Returns the working directory path specified by the given launch
	 * configuration, or <code>null</code> if none.
	 *
	 * @param configuration
	 *            launch configuration
	 * @return the working directory path specified by the given launch
	 *         configuration, or <code>null</code> if none
	 * @exception CoreException
	 *                if unable to retrieve the attribute
	 */
	public IPath getWorkingDirectoryPath(ILaunchConfiguration configuration)
			throws CoreException {
		String path = configuration.getAttribute(
				ScriptLaunchConfigurationConstants.ATTR_WORKING_DIRECTORY,
				(String) null);
		if (path != null) {
			if (path.trim().length() == 0) {
				return null;
			}
			IStringVariableManager manager = VariablesPlugin.getDefault()
					.getStringVariableManager();
			try {
				path = manager.performStringSubstitution(path, false);
				return new Path(path);
			} catch (CoreException e) {
				DLTKLaunchingPlugin.log(e);
			}
		}
		return null;
	}

	/**
	 * Verifies the working directory specified by the given launch
	 * configuration exists, and returns the working directory, or
	 * <code>null</code> if none is specified.
	 *
	 * @param configuration
	 *            launch configuration
	 * @return the working directory specified by the given launch
	 *         configuration, or <code>null</code> if none
	 * @exception CoreException
	 *                if unable to retrieve the attribute
	 */
	public String verifyWorkingDirectory(ILaunchConfiguration configuration,
			IEnvironment environment) throws CoreException {
		IPath path = getWorkingDirectoryPath(configuration);
		if (path == null) {
			IPath dirPath = getDefaultWorkingDirectory(configuration);
			IFileHandle dir = environment.getFile(dirPath);
			if (dir != null) {
				if (!dir.isDirectory()) {
					abort(MessageFormat.format(
							LaunchingMessages.AbstractScriptLaunchConfigurationDelegate_Working_directory_does_not_exist___0__12,
							dir.toString()), null,
							ScriptLaunchConfigurationConstants.ERR_WORKING_DIRECTORY_DOES_NOT_EXIST);
				}
				return dir.toOSString();
			}
		} else {
			if (path.isAbsolute()) {
				IFileHandle dir = environment.getFile(path);
				if (dir.isDirectory()) {
					return dir.toOSString();
				}
				// This may be a workspace relative path returned by a variable.
				// However variable paths start with a slash and thus are
				// thought to
				// be absolute
				IResource res = getWorkspaceRoot().findMember(path);
				if (res instanceof IContainer && res.exists()) {
					return res.getLocation().toOSString();
				}
				abort(MessageFormat.format(
						LaunchingMessages.AbstractScriptLaunchConfigurationDelegate_Working_directory_does_not_exist___0__12,
						path.toString()), null,
						ScriptLaunchConfigurationConstants.ERR_WORKING_DIRECTORY_DOES_NOT_EXIST);
			} else {
				IResource res = getWorkspaceRoot().findMember(path);
				if (res instanceof IContainer && res.exists()) {
					return res.getLocation().toOSString();
				}
				abort(MessageFormat.format(
						LaunchingMessages.AbstractScriptLaunchConfigurationDelegate_Working_directory_does_not_exist___0__12,
						path.toString()), null,
						ScriptLaunchConfigurationConstants.ERR_WORKING_DIRECTORY_DOES_NOT_EXIST);
			}
		}
		return null;
	}

	/**
	 * Verifies a main script name is specified by the given launch
	 * configuration, and returns the script type name.
	 *
	 * @param configuration
	 *            launch configuration
	 * @return the main type name specified by the given launch configuration
	 * @exception CoreException
	 *                if unable to retrieve the attribute or the attribute is
	 *                unspecified
	 */
	public String verifyMainScriptName(ILaunchConfiguration configuration)
			throws CoreException {
		final String name = getMainScriptName(configuration);
		if (name == null) {
			abort(LaunchingMessages.AbstractScriptLaunchConfigurationDelegate_Main_type_not_specified_11,
					null,
					ScriptLaunchConfigurationConstants.ERR_UNSPECIFIED_MAIN_SCRIPT);
		}
		return name;
	}

	// Project path + script path
	protected String getScriptLaunchPath(ILaunchConfiguration configuration,
			IEnvironment scriptEnvironment) throws CoreException {
		final String mainScriptName = verifyMainScriptName(configuration);
		if (mainScriptName.length() != 0) {
			final IProject project = getProject(configuration);
			final IFile mainScript = project.getFile(new Path(mainScriptName));
			final URI scriptURI = mainScript.getLocationURI();
			if (scriptURI != null) {
				final IEnvironment environment = EnvironmentManager
						.getEnvironment(project);
				if (environment != null) {
					final IFileHandle file = environment.getFile(scriptURI);
					if (file != null) {
						if (!file.exists()) {
							abort(NLS.bind(
									LaunchingMessages.AbstractScriptLaunchConfigurationDelegate_Main_script_not_exist,
									file.toOSString()), null,
									ScriptLaunchConfigurationConstants.ERR_UNSPECIFIED_MAIN_SCRIPT);
						}
						return file.getPath().toOSString();
					} else {
						abort(NLS.bind(
								LaunchingMessages.AbstractScriptLaunchConfigurationDelegate_Main_script_not_resolved,
								mainScriptName), null,
								ScriptLaunchConfigurationConstants.ERR_UNSPECIFIED_MAIN_SCRIPT);
					}
				}
			}
		}
		return null;
	}

	// Should be overriden in for any language
	protected InterpreterConfig createInterpreterConfig(
			ILaunchConfiguration configuration, ILaunch launch)
			throws CoreException {

		// Validation already included
		IEnvironment scriptEnvironment = getScriptEnvironment(configuration);
		IExecutionEnvironment scriptExecEnvironment = scriptEnvironment
				.getAdapter(IExecutionEnvironment.class);
		String scriptLaunchPath = getScriptLaunchPath(configuration,
				scriptEnvironment);
		// if (scriptLaunchPath == null) {
		// return null;
		// }
		final IPath workingDirectory = new Path(
				getWorkingDirectory(configuration, scriptEnvironment));

		IPath mainScript = null;//
		if (scriptLaunchPath != null) {
			mainScript = new Path(scriptLaunchPath);
		}
		InterpreterConfig config = new InterpreterConfig(scriptEnvironment,
				mainScript, workingDirectory);

		// Script arguments
		String[] scriptArgs = getScriptArguments(configuration);
		config.addScriptArgs(scriptArgs);

		// Interpreter argument
		String[] interpreterArgs = getInterpreterArguments(configuration);
		config.addInterpreterArgs(interpreterArgs);

		// Environment
		// config.addEnvVars(DebugPlugin.getDefault().getLaunchManager()
		// .getNativeEnvironmentCasePreserved());
		final boolean append = configuration.getAttribute(
				ILaunchManager.ATTR_APPEND_ENVIRONMENT_VARIABLES, true);
		final Map<String, String> configEnv = configuration.getAttribute(
				ILaunchManager.ATTR_ENVIRONMENT_VARIABLES,
				(Map<String, String>) null);
		// build base environment
		final Map<String, String> env = new HashMap<>();
		if (append || configEnv == null) {
			Map<String, String> envVars = scriptExecEnvironment
					.getEnvironmentVariables(false);
			if (envVars != null) {
				env.putAll(envVars);
			}
		}
		if (configEnv != null) {
			for (Map.Entry<String, String> entry : configEnv.entrySet()) {
				final String key = entry.getKey();
				String value = entry.getValue();
				if (value != null) {
					value = VariablesPlugin.getDefault()
							.getStringVariableManager()
							.performStringSubstitution(value);
				}
				env.put(key, value);
			}
			/*
			 * TODO for win32 override values in case-insensitive way like in
			 * org.eclipse.debug.internal.core.LaunchManager#getEnvironment(...)
			 */
		}
		config.addEnvVars(env);

		return config;
	}

	private IEnvironment getScriptEnvironment(
			ILaunchConfiguration configuration) throws CoreException {
		IScriptProject scriptProject = AbstractScriptLaunchConfigurationDelegate
				.getScriptProject(configuration);
		return EnvironmentManager.getEnvironment(scriptProject);
	}

	protected void validateLaunchConfiguration(
			ILaunchConfiguration configuration, String mode, IProject project)
			throws CoreException {

		// Validation of available debugging engine
		if (ILaunchManager.DEBUG_MODE.equals(mode)) {
			if (!DebuggingEngineManager.getInstance()
					.hasSelectedDebuggingEngine(project,
							getNatureId(configuration))) {
				abort(LaunchingMessages.AbstractScriptLaunchConfigurationDelegate_debuggingEngineNotSelected,
						null,
						ScriptLaunchConfigurationConstants.ERR_NO_DEFAULT_DEBUGGING_ENGINE);
			}
		}
	}

	@Override
	public ILaunch getLaunch(ILaunchConfiguration configuration, String mode)
			throws CoreException {
		final Launch launch = new Launch(configuration, mode, null);
		if (ILaunchManager.DEBUG_MODE.equals(mode)) {
			setDebugConsoleAttributes(launch, configuration);
			setDebugOptions(launch, configuration);
		}
		return launch;
	}

	/**
	 * @since 2.0
	 */
	protected void setDebugOptions(final Launch launch,
			ILaunchConfiguration configuration) throws CoreException {
		if (configuration.getAttribute(
				ScriptLaunchConfigurationConstants.ENABLE_BREAK_ON_FIRST_LINE,
				false)) {
			launch.setAttribute(
					DLTKDebugLaunchConstants.ATTR_BREAK_ON_FIRST_LINE,
					DLTKDebugLaunchConstants.TRUE);
		}
	}

	/**
	 * @since 2.0
	 */
	protected void setDebugConsoleAttributes(final Launch launch,
			ILaunchConfiguration configuration) throws CoreException {
		if (!configuration.getAttribute(
				ScriptLaunchConfigurationConstants.ATTR_DEBUG_CONSOLE, true)) {
			launch.setAttribute(DLTKDebugLaunchConstants.ATTR_DEBUG_CONSOLE,
					DLTKDebugLaunchConstants.FALSE);
		}
	}

	@Override
	public void launch(ILaunchConfiguration configuration, String mode,
			ILaunch launch, IProgressMonitor monitor) throws CoreException {
		/*
		 * reset ATTR_CAPTURE_OUTPUT, since it's not used now. This attribute is
		 * set in ScriptCommonTab if interactive console is on, but at the
		 * moment we use another way, so this attribute should be removed.
		 *
		 * TODO #1: do it in migration delegate?
		 *
		 * TODO #2: modify ScriptCommonTab so, it would not set it.
		 */
		launch.setAttribute(DebugPlugin.ATTR_CAPTURE_OUTPUT, null);
		try {
			IScriptProject scriptProject = ScriptRuntime
					.getScriptProject(configuration);
			IProject project = scriptProject == null ? null
					: scriptProject.getProject();

			if (monitor == null) {
				monitor = new NullProgressMonitor();
			}

			monitor.beginTask(MessageFormat.format(
					LaunchingMessages.AbstractScriptLaunchConfigurationDelegate_startingLaunchConfiguration,
					new Object[] { configuration.getName() }), 10);
			if (monitor.isCanceled()) {
				return;
			}

			monitor.subTask(MessageFormat.format(
					LaunchingMessages.AbstractScriptLaunchConfigurationDelegate_validatingLaunchConfiguration,
					new Object[] { configuration.getName() }));
			validateLaunchConfiguration(configuration, mode, project);
			monitor.worked(1);
			if (monitor.isCanceled()) {
				return;
			}

			// Getting InterpreterConfig
			monitor.subTask(
					LaunchingMessages.AbstractScriptLaunchConfigurationDelegate_generatingInterpreterConfiguration);
			final InterpreterConfig config = createInterpreterConfig(
					configuration, launch);
			if (config == null) {
				monitor.setCanceled(true);
				return;
			}
			if (monitor.isCanceled()) {
				return;
			}
			monitor.worked(1);

			// Getting IInterpreterRunner
			monitor.subTask(
					LaunchingMessages.AbstractScriptLaunchConfigurationDelegate_gettingInterpreterRunner);
			final IInterpreterRunner runner = getInterpreterRunner(
					configuration, mode);
			if (monitor.isCanceled()) {
				return;
			}
			monitor.worked(1);

			// Real run
			monitor.subTask(
					LaunchingMessages.AbstractScriptLaunchConfigurationDelegate_executingRunner);
			runRunner(configuration, runner, config, launch,
					new SubProgressMonitor(monitor, 7));

		} catch (CoreException e) {
			tryHandleStatus(e, this);
		} catch (AssertionFailedException e) {
			tryHandleStatus(new CoreException(new Status(IStatus.ERROR,
					DLTKLaunchingPlugin.PLUGIN_ID,
					ScriptLaunchConfigurationConstants.ERR_INTERNAL_ERROR,
					e.getMessage(), e)), this);
		} catch (IllegalArgumentException e) {
			tryHandleStatus(new CoreException(new Status(IStatus.ERROR,
					DLTKLaunchingPlugin.PLUGIN_ID,
					ScriptLaunchConfigurationConstants.ERR_INTERNAL_ERROR,
					e.getMessage(), e)), this);
		} finally {
			monitor.done();
		}
	}

	protected static void tryHandleStatus(CoreException e, Object source)
			throws CoreException {
		final IStatus status = e.getStatus();

		final IStatusHandler handler = DebugPlugin.getDefault()
				.getStatusHandler(status);

		if (handler == null) {
			throw e;
		}

		handler.handleStatus(status, source);
	}

	protected void runRunner(ILaunchConfiguration configuration,
			IInterpreterRunner runner, InterpreterConfig config, ILaunch launch,
			IProgressMonitor monitor) throws CoreException {
		try {
			runner.run(config, launch, monitor);
		} catch (CoreException e) {
			tryHandleStatus(e, runner);
		}
	}

	protected String getWorkingDir(ILaunchConfiguration configuration,
			IEnvironment environment) throws CoreException {
		return verifyWorkingDirectory(configuration, environment);
	}

	protected IPath[] createBuildPath(ILaunchConfiguration configuration)
			throws CoreException {
		return createBuildPath(configuration,
				getScriptEnvironment(configuration));
	}

	protected IPath[] createBuildPath(ILaunchConfiguration configuration,
			IEnvironment environment) throws CoreException {
		List<Path> paths = new ArrayList<>();

		// Buildpath
		String[] buildpath = getBuildpath(configuration, environment);
		for (int i = 0; i < buildpath.length; i++) {
			paths.add(new Path(buildpath[i]));
		}

		// Bootpath
		String[] bootpath = getBootpath(configuration);
		if (bootpath != null) {
			// it may be null, if bootpath is standard
			for (int i = 0; i < bootpath.length; i++) {
				paths.add(new Path(bootpath[i]));
			}
		}

		return paths.toArray(new IPath[paths.size()]);
	}

	@Override
	protected IProject[] getBuildOrder(ILaunchConfiguration configuration,
			String mode) throws CoreException {
		return fOrderedProjects;
	}

	@Override
	protected IProject[] getProjectsForProblemSearch(
			ILaunchConfiguration configuration, String mode)
			throws CoreException {
		return fOrderedProjects;
	}

	@Override
	protected boolean isLaunchProblem(IMarker problemMarker)
			throws CoreException {
		return super.isLaunchProblem(problemMarker) && problemMarker.getType()
				.equals(IScriptModelMarker.DLTK_MODEL_PROBLEM_MARKER);
	}

	@Override
	public boolean preLaunchCheck(ILaunchConfiguration configuration,
			String mode, IProgressMonitor monitor) throws CoreException {

		if (monitor != null) {
			monitor.subTask(
					LaunchingMessages.AbstractScriptLaunchConfigurationDelegate_20);
		}

		fOrderedProjects = null;
		IScriptProject scriptProject = ScriptRuntime
				.getScriptProject(configuration);

		if (scriptProject != null) {
			fOrderedProjects = computeReferencedBuildOrder(
					new IProject[] { scriptProject.getProject() });
		}

		return super.preLaunchCheck(configuration, mode, monitor);
	}

	@Override
	protected IBreakpoint[] getBreakpoints(ILaunchConfiguration configuration) {
		// TODO
		return new IBreakpoint[] {};
	}

	/**
	 * Returns the Interpreter runner for the given launch mode to use when
	 * launching the given configuration.
	 *
	 * @param configuration
	 *            launch configuration
	 * @param mode
	 *            launch node
	 * @param project
	 *            project containing the launched resource
	 * @return Interpreter runner to use when launching the given configuration
	 *         in the given mode
	 * @throws CoreException
	 *             if a Interpreter runner cannot be determined
	 *
	 */
	public IInterpreterRunner getInterpreterRunner(
			ILaunchConfiguration configuration, String mode)
			throws CoreException {

		final IInterpreterInstall install = verifyInterpreterInstall(
				configuration);
		final IInterpreterRunner runner = install.getInterpreterRunner(mode);

		if (runner == null) {
			abort(MessageFormat.format(
					LaunchingMessages.InterpreterRunnerDoesntExist,
					install.getName(), mode), null,
					ScriptLaunchConfigurationConstants.ERR_INTERPRETER_RUNNER_DOES_NOT_EXIST);
		}

		return runner;
	}

	/**
	 * Returns an array of environment variables to be used when launching the
	 * given configuration or <code>null</code> if unspecified.
	 *
	 * @param configuration
	 *            launch configuration
	 * @throws CoreException
	 *             if unable to access associated attribute or if unable to
	 *             resolve a variable in an environment variable's value
	 *
	 */
	public String[] getEnvironment(ILaunchConfiguration configuration)
			throws CoreException {
		return DebugPlugin.getDefault().getLaunchManager()
				.getEnvironment(configuration);
	}

	/**
	 * Returns the default working directory for the given launch configuration,
	 * or <code>null</code> if none. Subclasses may override as necessary.
	 *
	 * @param configuration
	 * @return default working directory or <code>null</code> if none
	 * @throws CoreException
	 *             if an exception occurs computing the default working
	 *             directory
	 *
	 */
	protected IPath getDefaultWorkingDirectory(
			ILaunchConfiguration configuration) throws CoreException {
		// default working directory is the project if this config has a project
		final IProject project = getProject(configuration);
		if (project != null) {
			IEnvironment environment = EnvironmentManager
					.getEnvironment(project);
			if (environment != null) {
				final String mainScriptName = verifyMainScriptName(
						configuration);
				if (mainScriptName.length() == 0) {
					final URI projectURI = project.getLocationURI();
					if (projectURI != null) {
						final IFileHandle file = environment
								.getFile(projectURI);
						if (file != null) {
							return file.getPath();
						}
					}
				} else {
					final Path scriptPath = new Path(mainScriptName);
					final IFile mainScript = project.getFile(scriptPath);
					final URI scriptURI = mainScript.getLocationURI();
					if (scriptURI != null) {
						final IFileHandle file = environment.getFile(scriptURI);
						if (file != null) {
							return file.getPath().removeLastSegments(
									scriptPath.segmentCount());
						}
					}
				}
			}
		}
		return null;
	}

	protected String getProjectLocation(ILaunchConfiguration configuration)
			throws CoreException {
		IProject project = getScriptProject(configuration).getProject();
		String loc = null;
		URI location = project.getLocationURI();
		if (location == null) {
			loc = project.getLocation().toOSString();
			return null;
		} else {
			loc = location.getPath();
		}
		return loc;
	}

	protected String getNatureId(ILaunchConfiguration configuration)
			throws CoreException {
		return configuration.getAttribute(
				ScriptLaunchConfigurationConstants.ATTR_SCRIPT_NATURE,
				(String) null);
	}

	abstract public String getLanguageId();

	public static ISourceModule getSourceModule(
			ILaunchConfiguration configuration) throws CoreException {
		String projectName = AbstractScriptLaunchConfigurationDelegate
				.getScriptProjectName(configuration);
		String mainScriptName = AbstractScriptLaunchConfigurationDelegate
				.getMainScriptName(configuration);
		IProject project = getWorkspaceRoot().getProject(projectName);

		IFile script = project.getFile(mainScriptName);

		ISourceModule module = (ISourceModule) DLTKCore.create(script);
		return module;
	}
}
