/*******************************************************************************
 * Copyright (c) 2000, 2013 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * 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];

		StringBuffer buf = new StringBuffer();
		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 --> 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<IRuntimeClasspathEntry>(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<String>(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;
	}
}