/*******************************************************************************
 * 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
 *     John-Mason P. Shackelford - bug 34548
 *******************************************************************************/
package org.eclipse.ant.internal.ui.launchConfigurations;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.ant.internal.ui.AntUIPlugin;
import org.eclipse.ant.internal.ui.AntUtil;
import org.eclipse.ant.internal.ui.IAntUIConstants;
import org.eclipse.ant.internal.ui.model.AntElementNode;
import org.eclipse.ant.internal.ui.model.AntProjectNode;
import org.eclipse.ant.internal.ui.model.AntTargetNode;
import org.eclipse.ant.internal.ui.model.AntTaskNode;
import org.eclipse.ant.launching.IAntLaunchConstants;
import org.eclipse.core.externaltools.internal.IExternalToolConstants;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.variables.VariablesPlugin;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationType;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.ui.CommonTab;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.debug.ui.ILaunchShortcut2;
import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.dialogs.ElementListSelectionDialog;
import org.eclipse.ui.editors.text.ILocationProvider;
import org.eclipse.ui.externaltools.internal.launchConfigurations.ExternalToolsUtil;

import com.ibm.icu.text.MessageFormat;

/**
 * This class provides the Run/Debug As -> Ant Build launch shortcut.
 * 
 */
public class AntLaunchShortcut implements ILaunchShortcut2 {

	private boolean fShowDialog= false;
	private static final int MAX_TARGET_APPEND_LENGTH = 30;
	private static final String DEFAULT_TARGET = "default"; //$NON-NLS-1$

	/**
	 * @see org.eclipse.debug.ui.ILaunchShortcut#launch(org.eclipse.jface.viewers.ISelection, java.lang.String)
	 */
	public void launch(ISelection selection, String mode) {
		if (selection instanceof IStructuredSelection) {
			IStructuredSelection structuredSelection = (IStructuredSelection)selection;
			Object object = structuredSelection.getFirstElement();
			if (object instanceof IAdaptable) {
				if (object instanceof AntElementNode) {
					launch((AntElementNode) object, mode);
					return;
				}
				IResource resource = (IResource)((IAdaptable)object).getAdapter(IResource.class);
				if (resource != null) {
					if (!(AntUtil.isKnownAntFile(resource))) {
						if (!AntUtil.isKnownBuildfileName(resource.getName())) {
							if (resource.getType() == IResource.FILE) {
								resource = resource.getParent();
							}
							resource = findBuildFile((IContainer)resource);
						}
					} 
					if (resource != null) {
						IFile file = (IFile) resource;
						launch(file.getFullPath(), file.getProject(), mode, null);
						return;
					}
				}
			}
		}
		antFileNotFound();
	}
	
	/**
	 * Launches the given Ant node.
	 * <ul><li>AntProjectNodes: the default target is executed</li>
	 * <li>AntTargetNodes: that target is executed</li>
	 * <li>AntTaskNodes: the owning target is executed</li>
	 * </ul>
	 * @param node the Ant node to use as the context for the launch
     * @param mode the mode of the launch
	 */
	public void launch(AntElementNode node, String mode) {
		String selectedTargetName= null;
		if (node instanceof AntTargetNode) {
			AntTargetNode targetNode= (AntTargetNode) node;
			if (targetNode.isDefaultTarget()) {
				selectedTargetName= DEFAULT_TARGET;
			} else {
				// append a comma to be consistent with ant targets tab
				selectedTargetName= targetNode.getTarget().getName() + ',';
			}
		} else if (node instanceof AntProjectNode) {
			selectedTargetName = DEFAULT_TARGET;
		} else if (node instanceof AntTaskNode) {
		    AntTaskNode taskNode= (AntTaskNode) node;
		    selectedTargetName= taskNode.getTask().getOwningTarget().getName();
		}
	
		IFile file = node.getBuildFileResource();
		if (file != null) {
			launch(file.getFullPath(), file.getProject(), mode, selectedTargetName);
			return;
		} 
		//external buildfile
		IWorkbenchPage page = AntUIPlugin.getActiveWorkbenchWindow().getActivePage();
		IPath filePath = null;
		IEditorPart editor= page.getActiveEditor();
		if (editor != null) {
		    IEditorInput editorInput = editor.getEditorInput();
		    ILocationProvider locationProvider= (ILocationProvider)editorInput.getAdapter(ILocationProvider.class);
		    if (locationProvider != null) {
		        filePath= locationProvider.getPath(editorInput);
		        if (filePath != null) {
					launch(filePath, null, mode, selectedTargetName);
					return;
				}
		    }
		}
		antFileNotFound();
	}
	
	/**
	 * Inform the user that an ant file was not found to run.
	 */
	private void antFileNotFound() {
		reportError(AntLaunchConfigurationMessages.AntLaunchShortcut_Unable, null);	
	}

	/**
	 * Walks the file hierarchy looking for a build file.
	 * Returns the first build file found that matches the 
	 * search criteria.
	 */
	private IFile findBuildFile(IContainer parent) {
		String[] names= AntUtil.getKnownBuildfileNames();
		if (names == null) {
			return null;
		}
		IContainer lparent = parent;
		IResource file= null;
		while (file == null || file.getType() != IResource.FILE) {		
			for (int i = 0; i < names.length; i++) {
				String string = names[i];
				file= lparent.findMember(string);
				if (file != null && file.getType() == IResource.FILE) {
					break;
				}
			}
			lparent = lparent.getParent();
			if (lparent == null) {
				return null;
			}
		}
		return (IFile)file;
	}
	
	/**
	 * Returns a listing of <code>ILaunchConfiguration</code>s that correspond to the specified build file.
	 * 
	 * @param filepath the path to the buildfile to launch
	 * @return the list of <code>ILaunchConfiguration</code>s that correspond to the specified build file.
	 * 
	 * @since 3.4
	 */
	protected List collectConfigurations(IPath filepath) {
		ILaunchManager manager = DebugPlugin.getDefault().getLaunchManager();
		ILaunchConfigurationType type = manager.getLaunchConfigurationType(IAntLaunchConstants.ID_ANT_LAUNCH_CONFIGURATION_TYPE);
		if(type != null) {
			try {
				ILaunchConfiguration[] configs = manager.getLaunchConfigurations(type);
				ArrayList list = new ArrayList();
				IPath location = null;
				for(int i = 0; i < configs.length; i++) {
					if(configs[i].exists()) {
						try {
							location = ExternalToolsUtil.getLocation(configs[i]);
							if(location != null && location.equals(filepath)) {
								list.add(configs[i]);
							}
						}
						catch(CoreException ce) {}
					}
				}
				return list;
			} catch (CoreException e) {}
		}
		return new ArrayList();
	}
	
	/**
	 * Returns a unique name for a copy of the given launch configuration with the given
	 * targets. The name seed is the same as the name for a new launch configuration with
	 *   &quot; [targetList]&quot; appended to the end.
	 * @param filePath the path to the buildfile
     * @param projectName the name of the project containing the buildfile or <code>null</code> if no project is known
	 * @param targetAttribute the listing of targets to execute or <code>null</code> for default target execution
	 * @return a unique name for the copy
	 */
	public static String getNewLaunchConfigurationName(IPath filePath, String projectName, String targetAttribute) {
		StringBuffer buffer = new StringBuffer();
		if (projectName != null) {
			buffer.append(projectName);
			buffer.append(' ');
			buffer.append(filePath.lastSegment());
		} else {
			buffer.append(filePath.lastSegment());
		}
		
		if (targetAttribute != null) {
			buffer.append(" ["); //$NON-NLS-1$
			if (targetAttribute.length() > MAX_TARGET_APPEND_LENGTH + 3) {
				// The target attribute can potentially be a long, comma-separated list
				// of target. Make sure the generated name isn't extremely long.
				buffer.append(targetAttribute.substring(0, MAX_TARGET_APPEND_LENGTH));
				buffer.append("..."); //$NON-NLS-1$
			} else {
				buffer.append(targetAttribute);
			}
			buffer.append(']');
		}
		
		String name= DebugPlugin.getDefault().getLaunchManager().generateLaunchConfigurationName(buffer.toString());
		return name;
	}
	
	/**
	 * Launch the given targets in the given build file. The targets are
	 * launched in the given mode.
	 * 
	 * @param filePath the path to the build file to launch
	 * @param project the project for the path
	 * @param mode the mode in which the build file should be executed
	 * @param targetAttribute the targets to launch or <code>null</code> to use targets on existing configuration,
	 *  or <code>DEFAULT</code> for default target explicitly.
	 *  
	 * configuration targets attribute.
	 */
	public void launch(IPath filePath, IProject project, String mode, String targetAttribute) {
		ILaunchConfiguration configuration = null;
		IFile backingfile = null;
		if(project != null) {
			//need to get the full location of a workspace file to compare against the resolved config location attribute
			backingfile = project.getFile(filePath.removeFirstSegments(1));
		}
		List configs = collectConfigurations((backingfile != null && backingfile.exists() ? backingfile.getLocation() : filePath));
		if (configs.isEmpty()) {
			configuration = createDefaultLaunchConfiguration(filePath, (project != null && project.exists() ? project : null));
		} else if (configs.size() == 1) {
			configuration= (ILaunchConfiguration)configs.get(0);
		} else {
			configuration = chooseConfig(configs);
			if(configuration == null) {
				//fail gracefully if the user cancels choosing a configuration
				return;
			}
		}
		
		// set the target to run, if applicable
		if (configuration != null) {
			try {
				if (targetAttribute != null && !targetAttribute.equals(configuration.getAttribute(IAntLaunchConstants.ATTR_ANT_TARGETS, DEFAULT_TARGET))) {
					ILaunchConfigurationWorkingCopy copy = configuration.getWorkingCopy();
					String attrValue = null;
					if (!DEFAULT_TARGET.equals(targetAttribute)) {
						attrValue = targetAttribute;
					}
					copy.setAttribute(IAntLaunchConstants.ATTR_ANT_TARGETS, attrValue);
					configuration = copy.doSave();
				}
			} catch (CoreException exception) {
				reportError(MessageFormat.format(AntLaunchConfigurationMessages.AntLaunchShortcut_Exception_launching, new String[] {filePath.toFile().getName()}), exception);
				return;
			}
			launch(mode, configuration);
		} else {
			antFileNotFound();
		}
	}
	
	/**
	 * Delegate method to launch the specified <code>ILaunchConfiguration</code> in the specified mode
	 * @param mode the mode to launch in
	 * @param configuration the <code>ILaunchConfiguration</code> to launch
	 */
	private void launch(String mode, ILaunchConfiguration configuration) {
        if (fShowDialog) {
			// Offer to save dirty editors before opening the dialog as the contents
			// of an Ant editor often affect the contents of the dialog.
			if (!DebugUITools.saveBeforeLaunch()) {
				return;
			}
			IStatus status = new Status(IStatus.INFO, IAntUIConstants.PLUGIN_ID, IAntUIConstants.STATUS_INIT_RUN_ANT, "", null); //$NON-NLS-1$
			String groupId;
			if (mode.equals(ILaunchManager.DEBUG_MODE)) {
			    groupId= IDebugUIConstants.ID_DEBUG_LAUNCH_GROUP;
			} else {
			    groupId= org.eclipse.ui.externaltools.internal.model.IExternalToolConstants.ID_EXTERNAL_TOOLS_LAUNCH_GROUP;
			}
			DebugUITools.openLaunchConfigurationDialog(AntUIPlugin.getActiveWorkbenchWindow().getShell(), configuration, groupId, status);
		} else {
			DebugUITools.launch(configuration, mode);
		}
    }
	
	/**
	 * Creates and returns a default launch configuration for the given file.
	 * 
	 * @param file
	 * @return default launch configuration
	 */
	public static ILaunchConfiguration createDefaultLaunchConfiguration(IFile file) {
		return createDefaultLaunchConfiguration(file.getFullPath(), file.getProject());
	}

	/**
	 * Creates and returns a default launch configuration for the given file path
	 * and project.
	 * 
	 * @param filePath the path to the buildfile
	 * @param project the project containing the buildfile or <code>null</code> if the
	 * buildfile is not contained in a project (is external).
	 * @return default launch configuration or <code>null</code> if one could not be created
	 */
	public static ILaunchConfiguration createDefaultLaunchConfiguration(IPath filePath, IProject project) {
		ILaunchManager manager = DebugPlugin.getDefault().getLaunchManager();
		ILaunchConfigurationType type = manager.getLaunchConfigurationType(IAntLaunchConstants.ID_ANT_LAUNCH_CONFIGURATION_TYPE);
				
		String projectName= project != null ? project.getName() : null;
		String name = getNewLaunchConfigurationName(filePath, projectName, null);
		try {
			ILaunchConfigurationWorkingCopy workingCopy = type.newInstance(null, name);
			if (project != null) {
				workingCopy.setAttribute(IExternalToolConstants.ATTR_LOCATION,
						VariablesPlugin.getDefault().getStringVariableManager().generateVariableExpression("workspace_loc", filePath.toString())); //$NON-NLS-1$
			} else {
				workingCopy.setAttribute(IExternalToolConstants.ATTR_LOCATION, filePath.toString());
			}
			workingCopy.setAttribute(IJavaLaunchConfigurationConstants.ATTR_CLASSPATH_PROVIDER, "org.eclipse.ant.ui.AntClasspathProvider"); //$NON-NLS-1$
			// set default for common settings
			CommonTab tab = new CommonTab();
			tab.setDefaults(workingCopy);
			tab.dispose();
			
			//set the project name so that the correct default VM install can be determined
			if (project != null) {
				workingCopy.setAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, project.getName());
			}
			AntJRETab jreTab = new AntJRETab();
			jreTab.setDefaults(workingCopy);
			jreTab.dispose();
			
			IFile file= AntUtil.getFileForLocation(filePath.toString(), null);
			workingCopy.setMappedResources(new IResource[] {file});
			
			return workingCopy.doSave();
		} catch (CoreException e) {
			reportError(MessageFormat.format(AntLaunchConfigurationMessages.AntLaunchShortcut_2, new String[]{filePath.toString()}), e);
		}
		return null;
	}
	
	/**
	 * Returns a list of existing launch configuration for the given file.
	 * 
	 * @param file the buildfile resource
	 * @return list of launch configurations
	 */
	public static List findExistingLaunchConfigurations(IFile file) {
		List validConfigs = new ArrayList();
		if(file != null) {
			IPath filePath = file.getLocation();
			if(filePath != null) {
				ILaunchManager manager = DebugPlugin.getDefault().getLaunchManager();
				ILaunchConfigurationType type = manager.getLaunchConfigurationType(IAntLaunchConstants.ID_ANT_LAUNCH_CONFIGURATION_TYPE);
				if (type != null) {
					try {
						ILaunchConfiguration[] configs = manager.getLaunchConfigurations(type);
						for (int i = 0; i < configs.length; i++) {
							try {
								if (filePath.equals(ExternalToolsUtil.getLocation(configs[i]))) {
									validConfigs.add(configs[i]);
								}
							}
							catch(CoreException ce) {}
						}
					} catch (CoreException e) {
						reportError(AntLaunchConfigurationMessages.AntLaunchShortcut_3, e);
					}
				}
			}
		}
		return validConfigs;
	}
	
	/**
	 * Prompts the user to choose from the list of given launch configurations
	 * and returns the config the user choose or <code>null</code> if the user
	 * pressed Cancel or if the given list is empty.
	 */
	public static ILaunchConfiguration chooseConfig(List configs) {
		if (configs.isEmpty()) {
			return null;
		}
		ILabelProvider labelProvider = DebugUITools.newDebugModelPresentation();
		ElementListSelectionDialog dialog= new ElementListSelectionDialog(Display.getDefault().getActiveShell(), labelProvider);
		dialog.setElements(configs.toArray(new ILaunchConfiguration[configs.size()]));
		dialog.setTitle(AntLaunchConfigurationMessages.AntLaunchShortcut_4);
		dialog.setMessage(AntLaunchConfigurationMessages.AntLaunchShortcut_5);
		dialog.setMultipleSelection(false);
		int result = dialog.open();
		labelProvider.dispose();
		if (result == Window.OK) {
			return (ILaunchConfiguration) dialog.getFirstResult();
		}
		return null;
	}

	/**
	 * @see org.eclipse.debug.ui.ILaunchShortcut#launch(org.eclipse.ui.IEditorPart, java.lang.String)
	 */
	public void launch(IEditorPart editor, String mode) {
		IEditorInput input = editor.getEditorInput();
		IFile file = (IFile)input.getAdapter(IFile.class);
		IPath filepath = null;
		if (file != null) {
			filepath = file.getFullPath();
		}
		if(filepath == null) {
		    ILocationProvider locationProvider= (ILocationProvider)input.getAdapter(ILocationProvider.class);
		    if (locationProvider != null) {
				filepath = locationProvider.getPath(input);
			}
		}
		if(filepath != null && AntUtil.isKnownAntFile(file)) {
			launch(filepath, (file == null ? null : file.getProject()), mode, null);
			return;
		}
		if (file != null) {
			if(!AntUtil.isKnownBuildfileName(file.getName())) {
				file = findBuildFile(file.getParent());
			}
			if (file != null) {
				launch(file.getFullPath(), file.getProject(), mode, null);
				return;
			}
		}
		antFileNotFound();
	}
	
	/**
	 * Opens an error dialog presenting the user with the specified message and throwable
	 * @param message
	 * @param throwable
	 */
	protected static void reportError(String message, Throwable throwable) {
		IStatus status = null;
		if (throwable instanceof CoreException) {
			status = ((CoreException)throwable).getStatus();
		} else {
			status = new Status(IStatus.ERROR, IAntUIConstants.PLUGIN_ID, 0, message, throwable);
		}
		ErrorDialog.openError(AntUIPlugin.getActiveWorkbenchWindow().getShell(), AntLaunchConfigurationMessages.AntLaunchShortcut_Error_7, AntLaunchConfigurationMessages.AntLaunchShortcut_Build_Failed_2, status); 
	}

	/**
	 * Sets whether to show the external tools launch configuration dialog
	 * 
	 * @param showDialog If true the launch configuration dialog will always be
	 * 			shown
	 */
	public void setShowDialog(boolean showDialog) {
		fShowDialog = showDialog;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.ui.ILaunchShortcut2#getLaunchConfigurations(org.eclipse.jface.viewers.ISelection)
	 */
	public ILaunchConfiguration[] getLaunchConfigurations(ISelection selection) {
		if (selection instanceof IStructuredSelection) {
			IStructuredSelection structuredSelection = (IStructuredSelection)selection;
			Object object = structuredSelection.getFirstElement();
			if (object instanceof IAdaptable) {
				if (object instanceof AntElementNode) {
					// return an empty list so that the shortcut is delegated to and we can prompt
					// the user for which config to run and specify the correct target
					return new ILaunchConfiguration[0];
				}
				IResource resource = (IResource)((IAdaptable)object).getAdapter(IResource.class);
				if (resource != null) {
					if (!(AntUtil.isKnownAntFile(resource))) {
						if (!AntUtil.isKnownBuildfileName(resource.getName())) {
							if (resource.getType() == IResource.FILE) {
								resource = resource.getParent();
							}
							resource = findBuildFile((IContainer)resource);
						}
					} 
					if (resource != null) {
						IPath location = ((IFile) resource).getLocation();
						if (location != null) {
							List list = collectConfigurations(location);
							return (ILaunchConfiguration[]) list.toArray(new ILaunchConfiguration[list.size()]);
						}
					}
				}
			}
		}
		return null;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.ui.ILaunchShortcut2#getLaunchConfigurations(org.eclipse.ui.IEditorPart)
	 */
	public ILaunchConfiguration[] getLaunchConfigurations(IEditorPart editor) {
		IEditorInput input = editor.getEditorInput();
		IFile file = (IFile)input.getAdapter(IFile.class);
		IPath filepath = null;
		if (file != null) {
			filepath = file.getLocation();
		}
		if(filepath == null) {
		    ILocationProvider locationProvider= (ILocationProvider)input.getAdapter(ILocationProvider.class);
		    if (locationProvider != null) {
				filepath = locationProvider.getPath(input);
			}
		}
		if(filepath != null && "xml".equals(filepath.getFileExtension())) { //$NON-NLS-1$
			List list = collectConfigurations(filepath);
			return (ILaunchConfiguration[]) list.toArray(new ILaunchConfiguration[list.size()]);
		}
		return null;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.ui.ILaunchShortcut2#getLaunchableResource(org.eclipse.jface.viewers.ISelection)
	 */
	public IResource getLaunchableResource(ISelection selection) {
		if (selection instanceof IStructuredSelection) {
			IStructuredSelection structuredSelection = (IStructuredSelection)selection;
			Object object = structuredSelection.getFirstElement();
			if (object instanceof IAdaptable) {
				IResource resource = (IResource)((IAdaptable)object).getAdapter(IResource.class);
				if (resource != null) {
					if (!(AntUtil.isKnownAntFile(resource))) {
						if(AntUtil.isKnownBuildfileName(resource.getName())) {
							return resource;
						}
						if (resource.getType() == IResource.FILE) {
							resource = resource.getParent();
						}
						resource = findBuildFile((IContainer)resource);
					} 
					return resource;
				}
			}
		}
		return null;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.ui.ILaunchShortcut2#getLaunchableResource(org.eclipse.ui.IEditorPart)
	 */
	public IResource getLaunchableResource(IEditorPart editor) {
		IEditorInput input = editor.getEditorInput();
		return (IFile)input.getAdapter(IFile.class);
	}
}
