/*******************************************************************************
 * 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 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
 *******************************************************************************/
package org.eclipse.ant.internal.launching;

import java.io.File;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.util.FileUtils;
import org.eclipse.ant.internal.core.IAntCoreConstants;
import org.eclipse.ant.internal.launching.launchConfigurations.AntHomeClasspathEntry;
import org.eclipse.ant.internal.launching.launchConfigurations.AntProcess;
import org.eclipse.ant.internal.launching.launchConfigurations.RemoteAntRuntimeProcess;
import org.eclipse.ant.launching.IAntLaunchConstants;
import org.eclipse.core.externaltools.internal.IExternalToolConstants;
import org.eclipse.core.externaltools.internal.model.ExternalToolBuilder;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
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.core.variables.VariablesPlugin;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.core.model.IProcess;
import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
import org.eclipse.jdt.launching.IRuntimeClasspathEntry;
import org.eclipse.jdt.launching.IRuntimeClasspathEntry2;
import org.eclipse.jdt.launching.JavaRuntime;

import com.ibm.icu.text.MessageFormat;

/**
 * General utility class dealing with Ant build files
 */
public final class AntLaunchingUtil {
	public static final String ATTRIBUTE_SEPARATOR = ","; //$NON-NLS-1$
	public static final char ANT_CLASSPATH_DELIMITER = '*';
	public static final String ANT_HOME_CLASSPATH_PLACEHOLDER = "G"; //$NON-NLS-1$
	public static final String ANT_GLOBAL_USER_CLASSPATH_PLACEHOLDER = "UG"; //$NON-NLS-1$

	/**
	 * No instances allowed
	 */
	private AntLaunchingUtil() {
		super();
	}

	/**
	 * Returns a single-string of the strings for storage.
	 * 
	 * @param strings
	 *            the array of strings
	 * @return a single-string representation of the strings or <code>null</code> if the array is empty.
	 */
	public static String combineStrings(String[] strings) {
		if (strings.length == 0)
			return null;

		if (strings.length == 1)
			return strings[0];

		StringBuilder buf = new StringBuilder();
		for (int i = 0; i < strings.length - 1; i++) {
			buf.append(strings[i]);
			buf.append(ATTRIBUTE_SEPARATOR);
		}
		buf.append(strings[strings.length - 1]);
		return buf.toString();
	}

	/**
	 * Returns an array of targets to be run, or <code>null</code> if none are specified (indicating the default target or implicit target should be
	 * run).
	 * 
	 * @param configuration
	 *            launch configuration
	 * @return array of target names, or <code>null</code>
	 * @throws CoreException
	 *             if unable to access the associated attribute
	 */
	public static String[] getTargetNames(ILaunchConfiguration configuration) throws CoreException {
		String attribute = null;
		if (IAntLaunchConstants.ID_ANT_BUILDER_LAUNCH_CONFIGURATION_TYPE.equals(configuration.getType().getIdentifier())) {
			attribute = getTargetNamesForAntBuilder(configuration);
		}
		if (attribute == null) {
			attribute = configuration.getAttribute(IAntLaunchConstants.ATTR_ANT_TARGETS, (String) null);
			if (attribute == null) {
				return null;
			}
		}

		return AntLaunchingUtil.parseRunTargets(attribute);
	}

	private static String getTargetNamesForAntBuilder(ILaunchConfiguration configuration) throws CoreException {
		String buildType = ExternalToolBuilder.getBuildType();
		String targets = null;
		if (IExternalToolConstants.BUILD_TYPE_AUTO.equals(buildType)) {
			targets = configuration.getAttribute(IAntLaunchConstants.ATTR_ANT_AUTO_TARGETS, (String) null);
		} else if (IExternalToolConstants.BUILD_TYPE_CLEAN.equals(buildType)) {
			targets = configuration.getAttribute(IAntLaunchConstants.ATTR_ANT_CLEAN_TARGETS, (String) null);
		} else if (IExternalToolConstants.BUILD_TYPE_FULL.equals(buildType)) {
			targets = configuration.getAttribute(IAntLaunchConstants.ATTR_ANT_AFTER_CLEAN_TARGETS, (String) null);
		} else if (IExternalToolConstants.BUILD_TYPE_INCREMENTAL.equals(buildType)) {
			targets = configuration.getAttribute(IAntLaunchConstants.ATTR_ANT_MANUAL_TARGETS, (String) null);
		}

		return targets;
	}

	/**
	 * Returns a map of properties to be defined for the build, or <code>null</code> if none are specified (indicating no additional properties
	 * specified for the build).
	 * 
	 * @param configuration
	 *            launch configuration
	 * @return map of properties (name --&gt; value), or <code>null</code>
	 * @throws CoreException
	 *             if unable to access the associated attribute
	 */
	public static Map<String, String> getProperties(ILaunchConfiguration configuration) throws CoreException {
		// TODO PLATFORM DEBUG 1.5 API
		Map<String, String> map = configuration.getAttribute(IAntLaunchConstants.ATTR_ANT_PROPERTIES, (Map<String, String>) null);
		return map;
	}

	/**
	 * Returns a String specifying the Ant home to use for the build.
	 * 
	 * @param configuration
	 *            launch configuration
	 * @return String specifying Ant home to use or <code>null</code>
	 * @throws CoreException
	 *             if unable to access the associated attribute
	 */
	public static String getAntHome(ILaunchConfiguration configuration) throws CoreException {
		IRuntimeClasspathEntry[] entries = JavaRuntime.computeUnresolvedRuntimeClasspath(configuration);
		for (int i = 0; i < entries.length; i++) {
			IRuntimeClasspathEntry entry = entries[i];
			if (entry.getType() == IRuntimeClasspathEntry.OTHER) {
				IRuntimeClasspathEntry2 entry2 = (IRuntimeClasspathEntry2) entry;
				if (entry2.getTypeId().equals(AntHomeClasspathEntry.TYPE_ID)) {
					return ((AntHomeClasspathEntry) entry2).getAntHome();
				}
			}
		}
		return null;
	}

	/**
	 * Returns an array of property files to be used for the build, or <code>null</code> if none are specified (indicating no additional property
	 * files specified for the build).
	 * 
	 * @param configuration
	 *            launch configuration
	 * @return array of property file names, or <code>null</code>
	 * @throws CoreException
	 *             if unable to access the associated attribute
	 */
	public static String[] getPropertyFiles(ILaunchConfiguration configuration) throws CoreException {
		String attribute = configuration.getAttribute(IAntLaunchConstants.ATTR_ANT_PROPERTY_FILES, (String) null);
		if (attribute == null) {
			return null;
		}
		String[] propertyFiles = AntLaunchingUtil.parseString(attribute, ","); //$NON-NLS-1$
		for (int i = 0; i < propertyFiles.length; i++) {
			String propertyFile = propertyFiles[i];
			propertyFile = expandVariableString(propertyFile, AntCoreModelMessages.AntUtil_6);
			propertyFiles[i] = propertyFile;
		}
		return propertyFiles;
	}

	/**
	 * Returns the list of URLs that define the custom classpath for the Ant build, or <code>null</code> if the global classpath is to be used.
	 * 
	 * @param config
	 *            launch configuration
	 * @return a list of <code>URL</code>
	 * 
	 * @throws CoreException
	 *             if file does not exist, IO problems, or invalid format.
	 */
	public static URL[] getCustomClasspath(ILaunchConfiguration config) throws CoreException {
		boolean useDefault = config.getAttribute(IJavaLaunchConfigurationConstants.ATTR_DEFAULT_CLASSPATH, true);
		if (useDefault) {
			return null;
		}
		IRuntimeClasspathEntry[] unresolved = JavaRuntime.computeUnresolvedRuntimeClasspath(config);
		// don't consider bootpath entries
		List<IRuntimeClasspathEntry> userEntries = new ArrayList<>(unresolved.length);
		for (int i = 0; i < unresolved.length; i++) {
			IRuntimeClasspathEntry entry = unresolved[i];
			if (entry.getClasspathProperty() == IRuntimeClasspathEntry.USER_CLASSES) {
				userEntries.add(entry);
			}
		}
		IRuntimeClasspathEntry[] entries = JavaRuntime.resolveRuntimeClasspath(userEntries.toArray(new IRuntimeClasspathEntry[userEntries.size()]), config);
		URL[] urls = new URL[entries.length];
		for (int i = 0; i < entries.length; i++) {
			IRuntimeClasspathEntry entry = entries[i];
			try {
				urls[i] = new URL(IAntCoreConstants.FILE_PROTOCOL + entry.getLocation());
			}
			catch (MalformedURLException e) {
				throw new CoreException(new Status(IStatus.ERROR, AntLaunching.getUniqueIdentifier(), AntLaunching.INTERNAL_ERROR, AntCoreModelMessages.AntUtil_7, e));
			}
		}
		return urls;
	}

	private static String expandVariableString(String variableString, String invalidMessage) throws CoreException {
		String expandedString = VariablesPlugin.getDefault().getStringVariableManager().performStringSubstitution(variableString);
		if (expandedString == null || expandedString.length() == 0) {
			String msg = MessageFormat.format(invalidMessage, new Object[] { variableString });
			throw new CoreException(new Status(IStatus.ERROR, AntLaunching.PLUGIN_ID, 0, msg, null));
		}
		return expandedString;
	}

	/**
	 * Returns the list of target names to run
	 * 
	 * @param extraAttibuteValue
	 *            the external tool's extra attribute value for the run targets key.
	 * @return a list of target names
	 */
	public static String[] parseRunTargets(String extraAttibuteValue) {
		return parseString(extraAttibuteValue, ATTRIBUTE_SEPARATOR);
	}

	/**
	 * Returns the list of Strings that were delimiter separated.
	 * 
	 * @param delimString
	 *            the String to be tokenized based on the delimiter
	 * @return a list of Strings
	 */
	public static String[] parseString(String delimString, String delim) {
		if (delimString == null) {
			return new String[0];
		}

		// Need to handle case where separator character is
		// actually part of the target name!
		StringTokenizer tokenizer = new StringTokenizer(delimString, delim);
		String[] results = new String[tokenizer.countTokens()];
		for (int i = 0; i < results.length; i++) {
			results[i] = tokenizer.nextToken().trim();
		}

		return results;
	}

	/**
	 * Returns an IFile with the given fully qualified path (relative to the workspace root). The returned IFile may or may not exist.
	 */
	public static IFile getFile(String fullPath) {
		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
		return root.getFile(new Path(fullPath));
	}

	/**
	 * Returns the workspace file associated with the given path in the local file system, or <code>null</code> if none. If the path happens to be a
	 * relative path, then the path is interpreted as relative to the specified parent file.
	 * 
	 * Attempts to handle linked files; the first found linked file with the correct path is returned.
	 * 
	 * @param path
	 * @param buildFileParent
	 * @return file or <code>null</code>
	 * @see org.eclipse.core.resources.IWorkspaceRoot#findFilesForLocation(IPath)
	 */
	public static IFile getFileForLocation(String path, File buildFileParent) {
		if (path == null) {
			return null;
		}
		IPath filePath = new Path(path);
		IFile file = null;
		URI location = filePath.makeAbsolute().toFile().toURI();
		IFile[] files = ResourcesPlugin.getWorkspace().getRoot().findFilesForLocationURI(location);
		if (files.length > 0) {
			file = files[0];
		}
		if (file == null) {
			// relative path
			File relativeFile = null;
			try {
				// this call is ok if buildFileParent is null
				relativeFile = FileUtils.getFileUtils().resolveFile(buildFileParent, path);
				filePath = new Path(relativeFile.getAbsolutePath());
				location = filePath.makeAbsolute().toFile().toURI();
				files = ResourcesPlugin.getWorkspace().getRoot().findFilesForLocationURI(location);
				if (files.length > 0) {
					file = files[0];
				} else {
					return null;
				}
			}
			catch (BuildException be) {
				return null;
			}
		}

		if (file.exists()) {
			return file;
		}
		File ioFile = file.getLocation().toFile();
		if (ioFile.exists()) {// needs to handle case insensitivity on WINOS
			files = ResourcesPlugin.getWorkspace().getRoot().findFilesForLocationURI(ioFile.toURI());
			if (files.length > 0) {
				return files[0];
			}
		}

		return null;
	}

	/**
	 * Migrates the classpath in the given configuration from the old format to the new format. The old format is not preserved. Instead, the default
	 * classpath will be used. However, ANT_HOME settings are preserved.
	 * 
	 * @param configuration
	 *            a configuration to migrate
	 * @throws CoreException
	 *             if unable to migrate
	 * @since 3.0
	 */
	@SuppressWarnings({ "restriction", "deprecation" })
	public static void migrateToNewClasspathFormat(ILaunchConfiguration configuration) throws CoreException {
		String oldClasspath = configuration.getAttribute(AntLaunching.ATTR_ANT_CUSTOM_CLASSPATH, (String) null);
		String oldAntHome = configuration.getAttribute(AntLaunching.ATTR_ANT_HOME, (String) null);
		String provider = configuration.getAttribute(IJavaLaunchConfigurationConstants.ATTR_CLASSPATH_PROVIDER, (String) null);
		if (oldClasspath != null || oldAntHome != null || provider == null) {
			ILaunchConfigurationWorkingCopy workingCopy = null;
			if (configuration.isWorkingCopy()) {
				workingCopy = (ILaunchConfigurationWorkingCopy) configuration;
			} else {
				workingCopy = configuration.getWorkingCopy();
			}
			workingCopy.setAttribute(AntLaunching.ATTR_ANT_CUSTOM_CLASSPATH, (String) null);
			workingCopy.setAttribute(AntLaunching.ATTR_ANT_HOME, (String) null);
			workingCopy.setAttribute(IJavaLaunchConfigurationConstants.ATTR_CLASSPATH_PROVIDER, "org.eclipse.ant.ui.AntClasspathProvider"); //$NON-NLS-1$
			workingCopy.setAttribute(IJavaLaunchConfigurationConstants.ATTR_DEFAULT_CLASSPATH, true);
			if (oldAntHome != null) {
				IRuntimeClasspathEntry[] entries = JavaRuntime.computeUnresolvedRuntimeClasspath(workingCopy);
				List<String> mementos = new ArrayList<>(entries.length);
				for (int i = 0; i < entries.length; i++) {
					IRuntimeClasspathEntry entry = entries[i];
					if (entry.getType() == IRuntimeClasspathEntry.OTHER) {
						IRuntimeClasspathEntry2 entry2 = (IRuntimeClasspathEntry2) entry;
						if (entry2.getTypeId().equals(AntHomeClasspathEntry.TYPE_ID)) {
							AntHomeClasspathEntry homeEntry = new AntHomeClasspathEntry(oldAntHome);
							mementos.add(homeEntry.getMemento());
							continue;
						}
					}
					mementos.add(entry.getMemento());
				}
				workingCopy.setAttribute(IJavaLaunchConfigurationConstants.ATTR_DEFAULT_CLASSPATH, false);
				workingCopy.setAttribute(IJavaLaunchConfigurationConstants.ATTR_CLASSPATH, mementos);
			}
			workingCopy.doSave();
		}
	}

	public static boolean isSeparateJREAntBuild(ILaunchConfiguration configuration) {
		boolean separateJRE = true;
		try {
			// always null for same JRE
			separateJRE = configuration.getAttribute(IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME, (String) null) != null;
		}
		catch (CoreException e) {
			AntLaunching.log(AntCoreModelMessages.AntUtil_2, e);
		}

		return separateJRE;
	}

	public static void linkBuildFailedMessage(String message, IProcess process) {
		String fileName = null;
		String lineNumber = ""; //$NON-NLS-1$
		int fileStart = 0;
		int index = message.indexOf("xml"); //$NON-NLS-1$
		if (index > 0) {
			int numberStart = index + 4;
			int numberEnd = message.indexOf(':', numberStart);
			int fileEnd = index + 3;
			if (numberStart > 0 && fileEnd > 0) {
				fileName = message.substring(fileStart, fileEnd).trim();
				if (numberEnd > 0) {
					lineNumber = message.substring(numberStart, numberEnd).trim();
				}
			}
		}

		if (fileName != null) {
			int num = -1;
			try {
				num = Integer.parseInt(lineNumber);
			}
			catch (NumberFormatException e) {
				// do nothing
			}
			URI location = new Path(fileName).makeAbsolute().toFile().toURI();
			IFile[] files = ResourcesPlugin.getWorkspace().getRoot().findFilesForLocationURI(location);
			IFile file = null;
			if (files.length > 0) {
				file = files[0];
			}
			if (file != null && file.exists()) {
				if (process != null) {
					ILaunch launch = null;
					if (process instanceof RemoteAntRuntimeProcess) {
						launch = ((RemoteAntRuntimeProcess) process).getLaunch();
					} else if (process instanceof AntProcess) {
						launch = ((AntProcess) process).getLaunch();
					}
					if (launch != null) {
						((AntLaunch) launch).addLinkDescriptor(message, fileName, num, 0, message.length());
					}
				}
			}
		}
	}

	/**
	 * Returns whether the given configuration should be launched in the background. When unspecified, the default value for an Ant launch
	 * configuration is <code>true</code>.
	 * 
	 * @param configuration
	 *            the configuration
	 * @return whether the configuration is configured to launch in the background
	 */
	public static boolean isLaunchInBackground(ILaunchConfiguration configuration) {
		boolean launchInBackground = true;
		try {
			launchInBackground = configuration.getAttribute(IExternalToolConstants.ATTR_LAUNCH_IN_BACKGROUND, true);
		}
		catch (CoreException ce) {
			AntLaunching.log(ce);
		}
		return launchInBackground;
	}
}