/*******************************************************************************
 * Copyright (c) 2000, 2009 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.core.externaltools.internal.model;

import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;

import org.eclipse.core.externaltools.internal.IExternalToolConstants;
import org.eclipse.core.externaltools.internal.registry.ExternalToolMigration;
import org.eclipse.core.resources.ICommand;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IncrementalProjectBuilder;
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.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.core.ILaunchManager;

/**
 * Utility methods for working with external tool project builders.
 */
public class BuilderCoreUtils {

	public static final String LAUNCH_CONFIG_HANDLE = "LaunchConfigHandle"; //$NON-NLS-1$

	/**
	 * Constant used to find a builder using the 3.0-interim format
	 */
	public static final String BUILDER_FOLDER_NAME = ".externalToolBuilders"; //$NON-NLS-1$
	/**
	 * Constant used to represent the current project in the 3.0-final format.
	 */
	public static final String PROJECT_TAG = "<project>"; //$NON-NLS-1$

	public static final String VERSION_1_0 = "1.0"; //$NON-NLS-1$
	public static final String VERSION_2_1 = "2.1"; //$NON-NLS-1$
	// The format shipped up to and including Eclipse 3.0 RC1
	public static final String VERSION_3_0_interim = "3.0.interim"; //$NON-NLS-1$
	// The format shipped in Eclipse 3.0 final
	public static final String VERSION_3_0_final = "3.0"; //$NON-NLS-1$

	private static final String BUILD_TYPE_SEPARATOR = ","; //$NON-NLS-1$
	private static final int[] DEFAULT_BUILD_TYPES = new int[] {
			IncrementalProjectBuilder.INCREMENTAL_BUILD,
			IncrementalProjectBuilder.FULL_BUILD };

	/**
	 * Returns a launch configuration from the given ICommand arguments. If the
	 * given arguments are from an old-style external tool, an unsaved working
	 * copy will be created from the arguments and returned.
	 * 
	 * @param commandArgs
	 *            the builder ICommand arguments
	 * @return a launch configuration, a launch configuration working copy, or
	 *         <code>null</code> if not possible.
	 */
	public static ILaunchConfiguration configFromBuildCommandArgs(
			IProject project, Map commandArgs, String[] version) {
		String configHandle = (String) commandArgs.get(LAUNCH_CONFIG_HANDLE);
		if (configHandle == null) {
			// Probably an old-style (Eclipse 1.0 or 2.0) external tool. Try to
			// migrate.
			version[0] = VERSION_1_0;
			return ExternalToolMigration.configFromArgumentMap(commandArgs);
		}
		ILaunchManager manager = DebugPlugin.getDefault().getLaunchManager();
		ILaunchConfiguration configuration = null;
		if (configHandle.startsWith(PROJECT_TAG)) {
			version[0] = VERSION_3_0_final;
			IPath path = new Path(configHandle);
			IFile file = project.getFile(path.removeFirstSegments(1));
			if (file.exists()) {
				configuration = manager.getLaunchConfiguration(file);
			}
		} else {
			// Try treating the handle as a file name.
			// This is the format used in 3.0 RC1.
			IPath path = new Path(BUILDER_FOLDER_NAME).append(configHandle);
			IFile file = project.getFile(path);
			if (file.exists()) {
				version[0] = VERSION_3_0_interim;
				configuration = manager.getLaunchConfiguration(file);
			} else {
				try {
					// Treat the configHandle as a memento. This is the format
					// used in Eclipse 2.1.
					configuration = manager
							.getLaunchConfiguration(configHandle);
				} catch (CoreException e) {
				}
				if (configuration != null) {
					version[0] = VERSION_2_1;
				}
			}
		}
		return configuration;
	}

	public static void configureTriggers(ILaunchConfiguration config,
			ICommand newCommand) throws CoreException {
		newCommand.setBuilding(IncrementalProjectBuilder.FULL_BUILD, false);
		newCommand.setBuilding(IncrementalProjectBuilder.INCREMENTAL_BUILD,
				false);
		newCommand.setBuilding(IncrementalProjectBuilder.AUTO_BUILD, false);
		newCommand.setBuilding(IncrementalProjectBuilder.CLEAN_BUILD, false);
		String buildKinds = config.getAttribute(
				IExternalToolConstants.ATTR_RUN_BUILD_KINDS, (String) null);
		int[] triggers = BuilderCoreUtils.buildTypesToArray(buildKinds);
		for (int i = 0; i < triggers.length; i++) {
			switch (triggers[i]) {
			case IncrementalProjectBuilder.FULL_BUILD:
				newCommand.setBuilding(IncrementalProjectBuilder.FULL_BUILD,
						true);
				break;
			case IncrementalProjectBuilder.INCREMENTAL_BUILD:
				newCommand.setBuilding(
						IncrementalProjectBuilder.INCREMENTAL_BUILD, true);
				break;
			case IncrementalProjectBuilder.AUTO_BUILD:
				newCommand.setBuilding(IncrementalProjectBuilder.AUTO_BUILD,
						true);
				break;
			case IncrementalProjectBuilder.CLEAN_BUILD:
				newCommand.setBuilding(IncrementalProjectBuilder.CLEAN_BUILD,
						true);
				break;
			}
		}
		if (!config.getAttribute(
				IExternalToolConstants.ATTR_TRIGGERS_CONFIGURED, false)) {
			ILaunchConfigurationWorkingCopy copy = config.getWorkingCopy();
			copy.setAttribute(IExternalToolConstants.ATTR_TRIGGERS_CONFIGURED,
					true);
			copy.doSave();
		}
	}

	/**
	 * Returns whether the given configuration is an "unmigrated" builder.
	 * Unmigrated builders are external tools that are stored in an old format
	 * but have not been migrated by the user. Old format builders are always
	 * translated into launch config working copies in memory, but they're not
	 * considered "migrated" until the config has been saved and the project
	 * spec updated.
	 * 
	 * @param config
	 *            the config to examine
	 * @return whether the given config represents an unmigrated builder
	 */
	public static boolean isUnmigratedConfig(ILaunchConfiguration config) {
		return config.isWorkingCopy()
				&& ((ILaunchConfigurationWorkingCopy) config).getOriginal() == null;
	}

	/**
	 * Converts the given config to a build command which is stored in the given
	 * command.
	 * 
	 * @return the configured build command
	 */
	public static ICommand toBuildCommand(IProject project,
			ILaunchConfiguration config, ICommand command) throws CoreException {
		Map args = null;
		if (isUnmigratedConfig(config)) {
			// This config represents an old external tool builder that hasn't
			// been edited. Try to find the old ICommand and reuse the
			// arguments.
			// The goal here is to not change the storage format of old,
			// unedited builders.
			ICommand[] commands = project.getDescription().getBuildSpec();
			for (int i = 0; i < commands.length; i++) {
				ICommand projectCommand = commands[i];
				String name = ExternalToolMigration
						.getNameFromCommandArgs(projectCommand.getArguments());
				if (name != null && name.equals(config.getName())) {
					args = projectCommand.getArguments();
					break;
				}
			}
		} else {
			if (config instanceof ILaunchConfigurationWorkingCopy) {
				ILaunchConfigurationWorkingCopy workingCopy = (ILaunchConfigurationWorkingCopy) config;
				if (workingCopy.getOriginal() != null) {
					config = workingCopy.getOriginal();
				}
			}
			args = new HashMap();
			// Launch configuration builders are stored with a project-relative
			// path
			StringBuffer buffer = new StringBuffer(PROJECT_TAG);
			// Append the project-relative path (workspace path minus first
			// segment)
			buffer.append('/').append(
					config.getFile().getFullPath().removeFirstSegments(1));
			args.put(LAUNCH_CONFIG_HANDLE, buffer.toString());
		}
		command.setBuilderName(ExternalToolBuilder.ID);
		command.setArguments(args);
		return command;
	}

	/**
	 * Returns the folder where project builders should be stored or
	 * <code>null</code> if the folder could not be created
	 */
	public static IFolder getBuilderFolder(IProject project, boolean create) {
		IFolder folder = project.getFolder(BUILDER_FOLDER_NAME);
		if (!folder.exists() && create) {
			try {
				folder.create(true, true, new NullProgressMonitor());
			} catch (CoreException e) {
				return null;
			}
		}
		return folder;
	}

	/**
	 * Migrates the launch configuration working copy, which is based on an old-
	 * style external tool builder, to a new, saved launch configuration. The
	 * returned launch configuration will contain the same attributes as the
	 * given working copy with the exception of the configuration name, which
	 * may be changed during the migration. The name of the configuration will
	 * only be changed if the current name is not a valid name for a saved
	 * config.
	 * 
	 * @param workingCopy
	 *            the launch configuration containing attributes from an
	 *            old-style project builder.
	 * @return ILaunchConfiguration a new, saved launch configuration whose
	 *         attributes match those of the given working copy as well as
	 *         possible
	 * @throws CoreException
	 *             if an exception occurs while attempting to save the new
	 *             launch configuration
	 */
	public static ILaunchConfiguration migrateBuilderConfiguration(
			IProject project, ILaunchConfigurationWorkingCopy workingCopy)
			throws CoreException {
		workingCopy.setContainer(getBuilderFolder(project, true));
		// Before saving, make sure the name is valid
		String name = workingCopy.getName();
		name = name.replace('/', '.');
		if (name.charAt(0) == ('.')) {
			name = name.substring(1);
		}
		IStatus status = ResourcesPlugin.getWorkspace().validateName(name,
				IResource.FILE);
		if (!status.isOK()) {
			name = "ExternalTool"; //$NON-NLS-1$
		}
		name = DebugPlugin.getDefault().getLaunchManager().generateLaunchConfigurationName(name);
		workingCopy.rename(name);
		return workingCopy.doSave();
	}

	/**
	 * Converts the build types string into an array of build kinds.
	 * 
	 * @param buildTypes
	 *            the string of built types to convert
	 * @return the array of build kinds.
	 */
	public static int[] buildTypesToArray(String buildTypes) {
		if (buildTypes == null || buildTypes.length() == 0) {
			return DEFAULT_BUILD_TYPES;
		}

		int count = 0;
		boolean incremental = false;
		boolean full = false;
		boolean auto = false;
		boolean clean = false;

		StringTokenizer tokenizer = new StringTokenizer(buildTypes,
				BUILD_TYPE_SEPARATOR);
		while (tokenizer.hasMoreTokens()) {
			String token = tokenizer.nextToken();
			if (IExternalToolConstants.BUILD_TYPE_INCREMENTAL.equals(token)) {
				if (!incremental) {
					incremental = true;
					count++;
				}
			} else if (IExternalToolConstants.BUILD_TYPE_FULL.equals(token)) {
				if (!full) {
					full = true;
					count++;
				}
			} else if (IExternalToolConstants.BUILD_TYPE_AUTO.equals(token)) {
				if (!auto) {
					auto = true;
					count++;
				}
			} else if (IExternalToolConstants.BUILD_TYPE_CLEAN.equals(token)) {
				if (!clean) {
					clean = true;
					count++;
				}
			}
		}

		int[] results = new int[count];
		count = 0;
		if (incremental) {
			results[count] = IncrementalProjectBuilder.INCREMENTAL_BUILD;
			count++;
		}
		if (full) {
			results[count] = IncrementalProjectBuilder.FULL_BUILD;
			count++;
		}
		if (auto) {
			results[count] = IncrementalProjectBuilder.AUTO_BUILD;
			count++;
		}
		if (clean) {
			results[count] = IncrementalProjectBuilder.CLEAN_BUILD;
			count++;
		}

		return results;
	}
}
