/*******************************************************************************
 * Copyright (c) 2008, 2019 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Jesper S Moller - Bug 421938: [1.8] ExecutionEnvironmentDescription#getVMArguments does not preserve VM arguments
 *******************************************************************************/
package org.eclipse.jdt.launching.environments;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.jdt.internal.launching.EEVMType;
import org.eclipse.jdt.internal.launching.LaunchingMessages;
import org.eclipse.jdt.internal.launching.LaunchingPlugin;
import org.eclipse.jdt.internal.launching.StandardVMType;
import org.eclipse.jdt.launching.LibraryLocation;
import org.eclipse.osgi.util.NLS;

/**
 * Helper class to parse and retrieve properties from execution environment description files. An execution environment description file can be used
 * to define attributes relevant the launching of a specific JRE configuration. The format of the file is defined by
 * <code>http://wiki.eclipse.org/Execution_Environment_Descriptions</code>.
 *
 * @since 3.5
 */
public final class ExecutionEnvironmentDescription {

	/**
	 * Endorsed directories property name in an execution environment description file.
	 */
	public static final String ENDORSED_DIRS = "-Dee.endorsed.dirs";  //$NON-NLS-1$
	/**
	 * Boot class path property name in an execution environment description file.
	 */
	public static final String BOOT_CLASS_PATH = "-Dee.bootclasspath";  //$NON-NLS-1$
	/**
	 * Source archive property name in an execution environment description file.
	 * Value is a path. When present, the source attachment for each library in the boot
	 * class path will be the file specified by this property.
	 */
	public static final String SOURCE_DEFAULT = "-Dee.src";  //$NON-NLS-1$
	/**
	 * Source map property name in an execution environment description file.
	 * <p>
	 * Maps class libraries to source attachments. Value is one or more entries of the form
	 * <code>libPath=sourcePath</code> separated by platform specific file separator. The paths
	 * can use <code>{$ee.home}</code> and <code>'..'</code> as well as the wild card characters
	 * '<code>?</code>" (any one character) and '<code>*</code>' (any number of characters).
	 * The <code>sourcePath</code> can use the wild card characters to have the source path be based on the
	 * wild card replacement in the <code>libPath</code>. In this case the wild card characters in the
	 * <code>sourcePath</code> must exist in the same order as the <code>libPath</code>.
	 * For example, <code>lib/foo*.???=source/src*foo.???</code>.
	 * </p>
	 */
	public static final String SOURCE_MAP = "-Dee.src.map";  //$NON-NLS-1$
	/**
	 * Javadoc location property name in an execution environment description file.
	 * <p>
	 * Specifies javadoc location for class libraries. Must be a URL. You can use
	 * <code>${ee.home}</code> and <code>'..'</code> segments to specify a file location
	 * relative to the ee file. If this property is not specified in the file,
	 * javadoc locations will be set to a default location based on the language level.
	 * </p>
	 */
	public static final String JAVADOC_LOC = "-Dee.javadoc";  //$NON-NLS-1$
	/**
	 * Pre-built index location property in an execution environment description file.
	 * <p>
	 * Specifies the location for a pre-built search index. Must be a valid {@link URL}.
	 *
	 * You can use <code>${ee.home}</code> and <code>'..'</code> segments to specify a file location
	 * relative to the ee file.
	 *
	 * If this property is not specified the default value of <code>null</code> will be used.
	 * </p>
	 * @since 3.7
	 */
	public static final String INDEX_LOC = "-Dee.index"; //$NON-NLS-1$
	/**
	 * Additional directories property name in an execution environment description file.
	 */
	public static final String ADDITIONAL_DIRS = "-Dee.additional.dirs";  //$NON-NLS-1$
	/**
	 * Extension directories property name in an execution environment description file.
	 */
	public static final String EXTENSION_DIRS = "-Dee.ext.dirs";  //$NON-NLS-1$
	/**
	 * Language level property name in an execution environment description file.
	 * For example, 1.4 or 1.5.
	 */
	public static final String LANGUAGE_LEVEL = "-Dee.language.level";  //$NON-NLS-1$
	/**
	 * OSGi profile property name in an execution environment description file.
	 * <p>
	 * The value is the identifier of an OSGi profile, such as <code>J2SE-1.4</code>.
	 * </p>
	 */
	public static final String CLASS_LIB_LEVEL = "-Dee.class.library.level";  //$NON-NLS-1$
	/**
	 * Executable property name in an execution environment description file.
	 * For example, <code>javaw.exe</code>.
	 */
	public static final String EXECUTABLE = "-Dee.executable";  //$NON-NLS-1$
	/**
	 * Console executable property name in an execution environment description file.
	 * For example, <code>java.exe</code>.
	 */
	public static final String EXECUTABLE_CONSOLE = "-Dee.executable.console";  //$NON-NLS-1$
	/**
	 * Java home property name in an execution environment description file.
	 * <p>
	 * The root install directory of the runtime environment or development kit. Corresponds to a value
	 * that could be used for <code>JAVA_HOME</code> environment variable
	 * </p>
	 */
	public static final String JAVA_HOME = "-Djava.home";  //$NON-NLS-1$
	/**
	 * Debug arguments property name in an execution environment description file.
	 * <p>
	 * The arguments to use to launch the VM in debug mode. For example
	 * <code>"-agentlib:jdwp=transport=dt_socket,suspend=y,address=localhost:${port}"</code>.
	 * The <code>${port}</code> variable will be substituted with a free port at launch time.
	 * When unspecified, default arguments are constructed based on the language level of the VM.
	 * </p>
	 */
	public static final String DEBUG_ARGS = "-Dee.debug.args";  //$NON-NLS-1$
	/**
	 * VM name property name in an execution environment description file.
	 * <p>
	 * The name is used as the JRE name when installing an EE JRE into Eclipse.
	 * </p>
	 */
	public static final String EE_NAME = "-Dee.name";  //$NON-NLS-1$
	/**
	 * The directory containing the execution environment description file. Relative paths are resolved
	 * relative to this location. This property will be set if not present, it does not need to be
	 * specified in the file.
	 */
	public static final String EE_HOME = "-Dee.home"; //$NON-NLS-1$

	/**
	 * Substitution in EE file - replaced with directory of EE file,
	 * to support absolute path names where needed. If the value is not in the
	 * file, it is set when properties are created.
	 */
	private static final String VAR_EE_HOME = "${ee.home}"; //$NON-NLS-1$

	/**
	 * Any line found in the description starting with this string will not be added to the
	 * VM argument list
	 */
	private static final String EE_ARG_FILTER = "-Dee."; //$NON-NLS-1$

	// Regex constants for handling the source mapping
	private static final Character WILDCARD_SINGLE_CHAR = new Character('?');
	private static final Character WILDCARD_MULTI_CHAR = new Character('*');
	private static final String REGEX_SPECIAL_CHARS = "+()^$.{}[]|\\"; //$NON-NLS-1$

	/**
	 * Execution environment description properties
	 */
	private Map<String, String> fProperties = null;

	/**
	 * Creates an execution environment description based on the properties defined in the given
	 * execution environment description file. The format of the file is defined by
	 * <code>http://wiki.eclipse.org/Execution_Environment_Descriptions</code>.
	 *
	 * @param eeFile execution environment description file
	 * @throws CoreException if unable to read or parse the file
	 */
	public ExecutionEnvironmentDescription(File eeFile) throws CoreException {
		initProperties(eeFile);
	}

	/**
	 * Returns a map of properties defined in this execution environment description.
	 * Properties in the file that do not have a value assigned to them are returned in the keys
	 * with an empty string as the value. Variable substitutions for <code>${ee.home}</code>
	 * have already been performed when resolving property values.
	 *
	 * @return properties as a map of {@link String} keys and values
	 */
	public Map<String, String> getProperties() {
		return fProperties;
	}

	/**
	 * Returns the specified property from this description, or <code>null</code>
	 * if none.
	 *
	 * @param property property name
	 * @return property value or <code>null</code>
	 */
	public String getProperty(String property) {
		return fProperties.get(property);
	}

	/**
	 * Returns the location of the system libraries defined in this execution environment.
	 * Libraries are generated from the endorsed directories, boot class path, additional
	 * directories, and extension directories specified by this description and are returned
	 * in that order. Source attachments are configured based on <code>src</code> and
	 * <code>src.map</code> properties.
	 *
	 * @return library locations, possibly empty
	 */
	public LibraryLocation[] getLibraryLocations() {
		List<LibraryLocation> allLibs = new ArrayList<>();

		String dirs = getProperty(ENDORSED_DIRS);
		if (dirs != null) {
			// Add all endorsed libraries - they are first, as they replace
			allLibs.addAll(StandardVMType.gatherAllLibraries(resolvePaths(dirs)));
		}

		// next is the boot path libraries
		dirs = getProperty(BOOT_CLASS_PATH);
		if (dirs != null) {
			String[] bootpath = resolvePaths(dirs);
			List<LibraryLocation> boot = new ArrayList<>(bootpath.length);
			IPath src = getSourceLocation();
			URL url = getJavadocLocation();
			URL indexurl = getIndexLocation();
			for (int i = 0; i < bootpath.length; i++) {
				IPath path = new Path(bootpath[i]);
				File lib = path.toFile();
				if (lib.exists() && lib.isFile()) {
					LibraryLocation libraryLocation = new LibraryLocation(path,	src, Path.EMPTY, url, indexurl);
					boot.add(libraryLocation);
				}
			}
			allLibs.addAll(boot);
		}

		// Add all additional libraries
		dirs = getProperty(ADDITIONAL_DIRS);
		if (dirs != null) {
			allLibs.addAll(StandardVMType.gatherAllLibraries(resolvePaths(dirs)));
		}

		// Add all extension libraries
		dirs = getProperty(EXTENSION_DIRS);
		if (dirs != null) {
			allLibs.addAll(StandardVMType.gatherAllLibraries(resolvePaths(dirs)));
		}


		//remove duplicates
		HashSet<String> set = new HashSet<>();
		LibraryLocation lib = null;
		for(ListIterator<LibraryLocation> liter = allLibs.listIterator(); liter.hasNext();) {
			lib = liter.next();
			if(!set.add(lib.getSystemLibraryPath().toOSString())) {
				//did not add it, duplicate
				liter.remove();
			}
		}

		// If the ee.src.map property is specified, use it to associate source locations with the libraries
		addSourceLocationsToLibraries(getSourceMap(), allLibs);

		return allLibs.toArray(new LibraryLocation[allLibs.size()]);
	}

	/**
	 * Returns VM arguments in this description or <code>null</code> if none. VM arguments
	 * correspond to all properties in this description that do not begin with "-Dee."
	 * concatenated together with spaces. Any single VM argument that contains spaces
	 * itself is surrounded with quotes.
	 *
	 * @return VM arguments or <code>null</code> if none
	 */
	public String getVMArguments() {
		StringBuilder arguments = new StringBuilder();
		Iterator<Entry<String, String>> entries = fProperties.entrySet().iterator();
		while (entries.hasNext()) {
			Entry<String, String> entry = entries.next();
			String key = entry.getKey();
			String value = entry.getValue();
			boolean appendArgument = !key.startsWith(EE_ARG_FILTER);
			if (appendArgument) {
				arguments.append(key);
				if (!value.equals("")) { //$NON-NLS-1$
					arguments.append('=');
					value = resolveHome(value);
					if (value.indexOf(' ') > -1){
						arguments.append('"').append(value).append('"');
					} else {
						arguments.append(value);
					}
				}
				arguments.append(' ');
			}
		}
		if (arguments.charAt(arguments.length()-1) == ' '){
			arguments.deleteCharAt(arguments.length()-1);
		}
		return arguments.toString();
	}

	/**
	 * Returns the executable for this description as a file or <code>null</code> if
	 * not specified.
	 *
	 * @return standard (non-console) executable or <code>null</code> if none
	 */
	public File getExecutable() {
		String property = getProperty(ExecutionEnvironmentDescription.EXECUTABLE);
		if (property != null) {
			String[] paths = resolvePaths(property);
			if (paths.length == 1) {
				return new File(paths[0]);
			}
		}
		return null;
	}

	/**
	 * Returns the console executable for this description as a file or <code>null</code> if
	 * not specified.
	 *
	 * @return console executable or <code>null</code> if none
	 */
	public File getConsoleExecutable() {
		String property = getProperty(ExecutionEnvironmentDescription.EXECUTABLE_CONSOLE);
		if (property != null) {
			String[] paths = resolvePaths(property);
			if (paths.length == 1) {
				return new File(paths[0]);
			}
		}
		return null;
	}

	/**
	 * Initializes the properties in the given execution environment
	 * description file.
	 *
	 * @param eeFile the EE file
	 * @exception CoreException if unable to read the file
	 */
	private void initProperties(File eeFile) throws CoreException {
		Map<String, String> properties = new LinkedHashMap<>();
		String eeHome = eeFile.getParentFile().getAbsolutePath();
		try (FileReader reader = new FileReader(eeFile); BufferedReader bufferedReader = new BufferedReader(reader);) {
			String line = bufferedReader.readLine();
			while (line != null) {
				if (!line.startsWith("#")) { //$NON-NLS-1$
					if (line.trim().length() > 0){
						int eq = line.indexOf('=');
						if (eq > 0) {
							String key = line.substring(0, eq);
							String value = null;
							if (line.length() > eq + 1) {
								value = line.substring(eq + 1).trim();
							}
							properties.put(key, value);
						} else {
							properties.put(line, ""); //$NON-NLS-1$
						}
					}
				}
				line = bufferedReader.readLine();
			}
		} catch (FileNotFoundException e) {
			throw new CoreException(new Status(IStatus.ERROR, LaunchingPlugin.ID_PLUGIN,
					NLS.bind(LaunchingMessages.ExecutionEnvironmentDescription_0,new String[]{eeFile.getPath()}), e));
		} catch (IOException e) {
			throw new CoreException(new Status(IStatus.ERROR, LaunchingPlugin.ID_PLUGIN,
					NLS.bind(LaunchingMessages.ExecutionEnvironmentDescription_1,new String[]{eeFile.getPath()}), e));
		}
		if (!properties.containsKey(EE_HOME)) {
			properties.put(EE_HOME, eeHome);
		}
		// resolve things with ${ee.home} in them
		fProperties = properties; // needs to be done to resolve
		Iterator<Entry<String, String>> entries = properties.entrySet().iterator();
		Map<String, String> resolved = new LinkedHashMap<>(properties.size());
		while (entries.hasNext()) {
			Entry<String, String> entry = entries.next();
			String key = entry.getKey();
			String value = entry.getValue();
			if (value != null) {
				value = resolveHome(value);
				resolved.put(key, value);
			} else {
				resolved.put(key, ""); //$NON-NLS-1$
			}
		}
		fProperties = resolved;
	}

	/**
	 * Replaces and returns a string with all occurrences of
	 * "${ee.home} replaced with its value.
	 *
	 * @param value string to process
	 * @return resolved string
	 */
	private String resolveHome(String value) {
		int start = 0;
		int index = value.indexOf(VAR_EE_HOME, start);
		StringBuilder replaced = null;
		String eeHome = getProperty(EE_HOME);
		while (index >= 0) {
			if (replaced == null) {
				replaced = new StringBuilder();
			}
			replaced.append(value.substring(start, index));
			replaced.append(eeHome);
			start = index + VAR_EE_HOME.length();
			index = value.indexOf(VAR_EE_HOME, start);
		}
		if (replaced != null) {
			replaced.append(value.substring(start));
			return replaced.toString();
		}
		return value;
	}

	/**
	 * Returns all path strings contained in the given string based on system
	 * path delimiter, resolved relative to the <code>${ee.home}</code> property.
	 *
	 * @param paths the paths to resolve
	 * @return array of individual paths
	 */
	private String[] resolvePaths(String paths) {
		String[] strings = paths.split(File.pathSeparator, -1);
		String eeHome = getProperty(EE_HOME);
		IPath root = new Path(eeHome);
		for (int i = 0; i < strings.length; i++) {
			strings[i] = makePathAbsolute(strings[i], root);
		}
		return strings;
	}

	/**
	 * Returns a string representing the absolute form of the given path.  If the
	 * given path is not absolute, it is appended to the given root path.  The returned
	 * path will always be the OS specific string form of the path.
	 *
	 * @param pathString string representing the path to make absolute
	 * @param root root to append non-absolute paths to
	 * @return absolute, OS specific path
	 */
	private String makePathAbsolute(String pathString, IPath root){
		IPath path = new Path(pathString.trim());
		if (!path.isEmpty() && !path.isAbsolute()) {
			IPath filePath = root.append(path);
			return filePath.toOSString();
		}
		return path.toOSString();
	}

	/**
	 * Creates a map (regex string to regex string) mapping library locations to their
	 * source locations.  This is done by taking the ee.src.map property from the ee file
	 * which allows a list of mappings that can use the wildcards ? (any one char) and *
	 * (any series of chars).  The property is converted to a map of regex strings used by
	 * {@link #addSourceLocationsToLibraries(Map, List)}.
	 * <pre>
	 * Example property, separated onto separate lines for easier reading
	 * -Dee.src.map=${ee.home}\lib\charconv?.zip=lib\charconv?-src.zip;
	 *              ${ee.home}\lib\jclDEE\classes.zip=lib\jclDEE\source\source.zip;
	 *              ${ee.home}\lib\jclDEE\*.zip=lib\jclDEE\source\*-src.zip;
	 *              ${ee.home}\lib\jclDEE\ext\*.???=lib\jclDEE\source\*-src.???;
	 * </pre>
	 *
	 *
	 * @return map containing regexs mapping library locations to their source locations
	 */
	private Map<String, String> getSourceMap(){
		String srcMapString = getProperty(SOURCE_MAP);
		Map<String, String> srcMap = new HashMap<>();
		if (srcMapString != null){
			// Entries must be separated by the file separator and have an equals splitting the lib location from the src location
			String[] entries = srcMapString.split(File.pathSeparator);
			for (int i = 0; i < entries.length; i++) {
				int index = entries[i].indexOf('=');
				if (index > 0 && index < entries[i].length()-1){
					IPath root = new Path(getProperty(EE_HOME));
					String key = entries[i].substring(0,index);
					String value = entries[i].substring(index+1);
					key = makePathAbsolute(key, root);
					value = makePathAbsolute(value, root);

					List<Character> wildcards = new ArrayList<>();
					StringBuilder keyBuffer = new StringBuilder();
				    char [] chars = key.toCharArray();
				    // Convert lib location to a regex, replace wildcards with grouped equivalents, keep track of used wildcards, allow '\' and '/' to be used, escape special chars
					for (int j = 0; j < chars.length; j++) {
						if (chars[j] == WILDCARD_MULTI_CHAR.charValue()) {
							wildcards.add(WILDCARD_MULTI_CHAR);
							keyBuffer.append("(.*)"); //$NON-NLS-1$
						} else if (chars[j] == WILDCARD_SINGLE_CHAR.charValue()) {
							wildcards.add(WILDCARD_SINGLE_CHAR);
							keyBuffer.append("(.)"); //$NON-NLS-1$
						} else if (REGEX_SPECIAL_CHARS.indexOf(chars[j]) != -1) {
							keyBuffer.append('\\').append(chars[j]);
						} else {
						    keyBuffer.append(chars[j]);
						}
					}

					int currentWild = 0;
					StringBuilder valueBuffer = new StringBuilder();
					chars = value.toCharArray();
					// Convert src location to a regex, replace wildcards with their group number, allow '\' and '/' to be used, escape special chars
					for (int j = 0; j < chars.length; j++) {
						if (chars[j] == WILDCARD_MULTI_CHAR.charValue() || chars[j] == WILDCARD_SINGLE_CHAR.charValue()) {
							if (currentWild < wildcards.size()){
								Character wild = wildcards.get(currentWild);
								if (chars[j] == wild.charValue()) {
									valueBuffer.append('$').append(currentWild+1);
									currentWild++;
								} else {
									LaunchingPlugin.log(NLS.bind(LaunchingMessages.EEVMType_5, new String[]{entries[i]}));
									break;
								}
							} else {
								LaunchingPlugin.log(NLS.bind(LaunchingMessages.EEVMType_5, new String[]{entries[i]}));
								break;
							}
						} else if (REGEX_SPECIAL_CHARS.indexOf(chars[j]) != -1) {
							valueBuffer.append('\\').append(chars[j]);
						} else {
							valueBuffer.append(chars[j]);
						}
					}

					srcMap.put(keyBuffer.toString(), valueBuffer.toString());

				} else {
					LaunchingPlugin.log(NLS.bind(LaunchingMessages.EEVMType_6, new String[]{entries[i]}));
				}
			}
		}
		return srcMap;
	}

	/**
	 * Uses the given src map to find source libraries that are associated with the
	 * library locations in the list.  The library locations are updated with the
	 * found source path.
	 *
	 * @param srcMap mapping of library location regexs to source location regexs
	 * @param libraries list of {@link LibraryLocation} objects to update with source locations
	 * @see #getSourceMap()
	 */
	private void addSourceLocationsToLibraries(Map<String, String> srcMap, List<LibraryLocation> libraries){
		for (Iterator<String> patternIterator = srcMap.keySet().iterator(); patternIterator.hasNext();) {
			// Try each library regex pattern and see what libraries apply.
			String currentKey = patternIterator.next();
			Pattern currentPattern = Pattern.compile(currentKey);
			Matcher matcher = currentPattern.matcher(""); //$NON-NLS-1$
			for (Iterator<LibraryLocation> locationIterator = libraries.iterator(); locationIterator.hasNext();) {
				LibraryLocation currentLibrary = locationIterator.next();
				matcher.reset(currentLibrary.getSystemLibraryPath().toOSString());
				if (matcher.find()){
					// Found a file that the pattern applies to, use the map to get the source location
					String sourceLocation = matcher.replaceAll(srcMap.get(currentKey));
					IPath sourcePath = new Path(sourceLocation);
					// Only add the source archive if it exists
					if (sourcePath.toFile().exists()){
						currentLibrary.setSystemLibrarySource(sourcePath);
					}

				}
			}
		}
	}

	/**
	 * Returns the location of the default source archive for this description or the empty
	 * path if none.
	 *
	 * @return default source archive location or Path.EMPTY if none
	 */
	private IPath getSourceLocation() {
		String src = getProperty(ExecutionEnvironmentDescription.SOURCE_DEFAULT);
		if (src != null) {
			String eeHome = getProperty(ExecutionEnvironmentDescription.EE_HOME);
			src = makePathAbsolute(src, new Path(eeHome));
			return new Path(src);
		}
		return Path.EMPTY;
	}

	/**
	 * Returns the javadoc location or <code>null</code> if unable to determine one.
	 * A default one is generated if not present, based on language level.
	 *
	 * @return javadoc location or <code>null</code> if none
	 */
	private URL getJavadocLocation() {
		return EEVMType.getJavadocLocation(fProperties);
	}

	/**
	 * Returns the {@link URL} for the index location or <code>null</code> if one has not been set.
	 *
	 * @return the index {@link URL} or <code>null</code>
	 * @since 3.7.0
	 */
	private URL getIndexLocation() {
		return EEVMType.getIndexLocation(fProperties);
	}
}
