/*******************************************************************************
 * Copyright (c) 2007, 2016 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
 *	   Daniel Friederich (freescale) -  Bug 293210 -  Context launch launches shared launch configuration twice.
 *******************************************************************************/
package org.eclipse.debug.internal.ui.contextlaunching;

import java.util.List;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchMode;
import org.eclipse.debug.internal.ui.DebugUIPlugin;
import org.eclipse.debug.internal.ui.IInternalDebugUIConstants;
import org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationManager;
import org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationSelectionDialog;
import org.eclipse.debug.internal.ui.launchConfigurations.LaunchShortcutExtension;
import org.eclipse.debug.internal.ui.launchConfigurations.LaunchShortcutSelectionDialog;
import org.eclipse.debug.internal.ui.stringsubstitution.SelectedResourceManager;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.debug.ui.ILaunchGroup;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.window.Window;
import org.eclipse.ui.IEditorPart;

import com.ibm.icu.text.MessageFormat;

/**
 * Static runner for context launching to provide the base capability of context 
 * launching to more than one form of action (drop down, toolbar, view, etc)
 * 
 * @see org.eclipse.debug.ui.actions.AbstractLaunchHistoryAction
 * @see org.eclipse.debug.ui.actions.LaunchShortcutsAction
 * @see org.eclipse.debug.ui.actions.ContextualLaunchAction
 * 
 *  @since 3.3
 */
public final class ContextRunner {
	
	/**
	 * The singleton instance of the context runner
	 */
	private static ContextRunner fgInstance = null;
	
	/**
	 * Returns the singleton instance of <code>ContextRunner</code>
	 * @return the singleton instance of <code>ContextRunner</code>
	 */
	public static ContextRunner getDefault() {
		if(fgInstance == null) {
			fgInstance = new ContextRunner();
		}
		return fgInstance;
	}
	
	/**
	 * The one instance of <code>LaunchingResourceManager</code> we need
	 * @since 3.4
	 */
	private LaunchingResourceManager fLRM = DebugUIPlugin.getDefault().getLaunchingResourceManager();
	
	/**
	 * Performs the context launching given the object context and the mode to
	 * launch in.
	 * 
	 * @param group the launch group to launch using
	 * @deprecated use launch(ILaunchGroup, boolean)
	 */
	@Deprecated
	public void launch(ILaunchGroup group) {
		launch(group, false);
	}
	
	/**
	 * Performs the context launching given the object context and the mode to
	 * launch in.
	 * 
	 * @param group the launch group to launch using
	 * @param isShift is Shift pressed (use <code>false</code> if no support for
	 *            Shift)
	 */
	public void launch(ILaunchGroup group, boolean isShift) {
		IStructuredSelection selection = SelectedResourceManager.getDefault().getCurrentSelection();
		IResource resource = SelectedResourceManager.getDefault().getSelectedResource();
		selectAndLaunch(resource, group, selection, isShift);
	}
	
	/**
	 * This method launches the last configuration that was launched, if any.
	 * 
	 * @param group the launch group to launch with
	 * @return true if there was a last launch and it was launched, false
	 *         otherwise
	 * @deprecated use launchLast(ILaunchGroup, boolean)
	 */
	@Deprecated
	protected boolean launchLast(ILaunchGroup group) {
		return launchLast(group, false);
	}

	/**
	 * This method launches the last configuration that was launched, if any.
	 * 
	 * @param group the launch group to launch with
	 * @param isShift is Shift pressed (use <code>false</code> if no support for
	 *            Shift)
	 * @return true if there was a last launch and it was launched, false
	 *         otherwise
	 */
	protected boolean launchLast(ILaunchGroup group, boolean isShift) {
		ILaunchConfiguration config = null;
		if(group != null) {
			config = DebugUIPlugin.getDefault().getLaunchConfigurationManager().getFilteredLastLaunch(group.getIdentifier());
			if(config != null) {
				launch(config, group.getMode(), isShift);
				return true;
			}
		}
		return false;
	}
	
	/**
	 * Prompts the user to select a way of launching the current resource, where
	 * a 'way' is defined as a launch shortcut.
	 * 
	 * @param resource the resource context
	 * @param group the launch group to launch with
	 * @param selection the current selection
	 * @deprecated use selectAndLaunch(IResource, ILaunchGroup,
	 *             IStructuredSelection, boolean)
	 */
	@Deprecated
	protected void selectAndLaunch(IResource resource, ILaunchGroup group, IStructuredSelection selection) {
		selectAndLaunch(resource, group, selection, false);
	}

	/**
	 * Prompts the user to select a way of launching the current resource, where
	 * a 'way' is defined as a launch shortcut.
	 * 
	 * @param resource the resource context
	 * @param group the launch group to launch with
	 * @param selection the current selection
	 * @param isShift is Shift pressed (use <code>false</code> if no support for
	 *            Shift)
	 */
	protected void selectAndLaunch(IResource resource, ILaunchGroup group, IStructuredSelection selection, boolean isShift) {
		if(group != null) {			
			LaunchConfigurationManager lcm = DebugUIPlugin.getDefault().getLaunchConfigurationManager();
			String mode = group.getMode();
			List<LaunchShortcutExtension> shortcuts = fLRM.getShortcutsForSelection(selection, mode);
		// allow the shortcut to translate/provide the resource for the launch
			IResource overrideResource = fLRM.getLaunchableResource(shortcuts, selection);
			if(overrideResource != null) {
				resource = overrideResource;
			}
			shortcuts = fLRM.pruneShortcuts(shortcuts, resource, mode);
		//see if the context is a shared configuration
			ILaunchConfiguration config = lcm.isSharedConfig(resource);
			if(config != null) {
				launch(config, mode, isShift);
				return;
			}
		//get the configurations from the resource and participants	
			List<ILaunchConfiguration> configs = fLRM.getParticipatingLaunchConfigurations(selection, resource, shortcuts, mode);
			int csize = configs.size();
			if(csize == 1) {
				launch(configs.get(0), mode, isShift);
			}
			else if(csize < 1) {
				int esize = shortcuts.size();
				if(esize == 1) {
					launchShortcut(selection, shortcuts.get(0), mode, isShift);
				}
				else if(esize > 1) {
					showShortcutSelectionDialog(resource, shortcuts, mode, selection, isShift);
				}
				else if(esize < 1) {
					if(DebugUIPlugin.getDefault().getPreferenceStore().getBoolean(IInternalDebugUIConstants.PREF_LAUNCH_LAST_IF_NOT_LAUNCHABLE)) {
						if (!launchLast(group, isShift)) {
							MessageDialog.openInformation(DebugUIPlugin.getShell(), ContextMessages.ContextRunner_0, ContextMessages.ContextRunner_7);
						}
					} else {
						if(resource != null) {
							IProject project = resource.getProject();
							if(project != null && !project.equals(resource)) {
								selectAndLaunch(project, group, new StructuredSelection(project), isShift);
							}
							else {
								String msg = ContextMessages.ContextRunner_7;
								if(!resource.isAccessible()) {
									msg = MessageFormat.format(ContextMessages.ContextRunner_13, new Object[] { resource.getName() });
								}
								MessageDialog.openInformation(DebugUIPlugin.getShell(), ContextMessages.ContextRunner_0, msg);
							}
						}
						else {
							if (!launchLast(group, isShift)) {
								MessageDialog.openInformation(DebugUIPlugin.getShell(), ContextMessages.ContextRunner_0, ContextMessages.ContextRunner_7);
							}
						}
					}
				}
			}
			else if(csize > 1){
				config = lcm.getMRUConfiguration(configs, group, resource);
				if(config != null) {
					launch(config, mode, isShift);
				} else {
					showConfigurationSelectionDialog(configs, mode, isShift);
				}
			}
		}
	}
	
	/**
	 * Validates the given launch mode and launches.
	 * 
	 * @param configuration configuration to launch
	 * @param mode launch mode identifier
	 * @param isShift is Shift pressed
	 */
	private void launch(ILaunchConfiguration configuration, String mode, boolean isShift) {
		if (validateMode(configuration, mode)) {
			DebugUITools.launch(configuration, mode, isShift);
		}
	}
	
	/**
	 * Delegate method that calls the appropriate launch method on a
	 * <code>LaunchShortcutExtension</code> given the current resource and
	 * selection context
	 * 
	 * @param selection the current selection
	 * @param shortcut the shortcut that wants to launch
	 * @param mode the mode to launch in
	 * @param isShift is Shift pressed
	 * 
	 * @since 3.4
	 */
	private void launchShortcut(IStructuredSelection selection, LaunchShortcutExtension shortcut, String mode, boolean isShift) {
		Object o = selection.getFirstElement();
		// store if Shift was pressed to toggle terminate before launch
		// preference
		if(o instanceof IEditorPart) {
			DebugUITools.storeLaunchToggleTerminate(o, isShift);
			shortcut.launch((IEditorPart) o, mode);
		}
		else {
			DebugUITools.storeLaunchToggleTerminate(selection, isShift);
			shortcut.launch(selection, mode);
		}
	}
	
	/**
	 * Validates the given launch mode is supported, and returns whether to continue with
	 * the launch.
	 * 
	 * @param configuration launch configuration
	 * @param mode launch mode
	 * @return whether the mode is supported
	 */
	private boolean validateMode(ILaunchConfiguration configuration, String mode) {
		try {
			// if this is a multi-mode launch, allow the launch dialog to be opened
			// to resolve a valid mode, if needed.
			if (configuration.getModes().isEmpty()) {
				if (!configuration.supportsMode(mode)) {
					ILaunchMode launchMode = DebugPlugin.getDefault().getLaunchManager().getLaunchMode(mode);
					if (launchMode == null) {
						DebugUIPlugin.logErrorMessage("Unsupported launch mode: " + mode); //$NON-NLS-1$
					} else {
						String label = launchMode.getLabel();
						String modeLabel = DebugUIPlugin.removeAccelerators(label);
						MessageDialog.openInformation(DebugUIPlugin.getShell(), MessageFormat.format(ContextMessages.ContextRunner_1, new Object[] { modeLabel }), MessageFormat.format(ContextMessages.ContextRunner_3, new Object[] {
								configuration.getName(),
								modeLabel.toLowerCase() }));
					}
					return false;
				}
			}
		} catch (CoreException e) {
			DebugUIPlugin.log(e.getStatus());
			return false;
		}
		return true;
	}
	
	/**
	 * Presents the user with a dialog to pick the launch configuration to
	 * launch and launches that configuration.
	 * 
	 * @param configurations the listing of applicable configurations to present
	 * @param mode the mode
	 * @deprecated use
	 *             showConfigurationSelectionDialog(List<ILaunchConfiguration>,
	 *             String, boolean)
	 */
	@Deprecated
	protected void showConfigurationSelectionDialog(List<ILaunchConfiguration> configurations, String mode) {
		showConfigurationSelectionDialog(configurations, mode, false);
	}

	/**
	 * Presents the user with a dialog to pick the launch configuration to
	 * launch and launches that configuration.
	 * 
	 * @param configurations the listing of applicable configurations to present
	 * @param mode the mode
	 * @param isShift is Shift pressed (use <code>false</code> if no support for
	 *            Shift)
	 */
	protected void showConfigurationSelectionDialog(List<ILaunchConfiguration> configurations, String mode, boolean isShift) {
		LaunchConfigurationSelectionDialog lsd = new LaunchConfigurationSelectionDialog(DebugUIPlugin.getShell(), configurations);
		if(lsd.open() == IDialogConstants.OK_ID) {
			ILaunchConfiguration config = (ILaunchConfiguration) lsd.getResult()[0];
			launch(config, mode, isShift);
		}
	}
	
	/**
	 * Presents a selection dialog to the user to pick a launch shortcut and
	 * launch using that shortcut.
	 * 
	 * @param resource the resource context
	 * @param shortcuts the list of applicable shortcuts
	 * @param mode the mode
	 * @param selection the current selection
	 * @deprecated use showShortcutSelectionDialog(IResource,
	 *             List<LaunchShortcutExtension>, String,IStructuredSelection,
	 *             boolean)
	 */
	@Deprecated
	protected void showShortcutSelectionDialog(IResource resource, List<LaunchShortcutExtension> shortcuts, String mode, IStructuredSelection selection) {
		showShortcutSelectionDialog(resource, shortcuts, mode, selection, false);
	}

	/**
	 * Presents a selection dialog to the user to pick a launch shortcut and
	 * launch using that shortcut.
	 * 
	 * @param resource the resource context
	 * @param shortcuts the list of applicable shortcuts
	 * @param mode the mode
	 * @param selection the current selection
	 * @param isShift is Shift pressed (use <code>false</code> if no support for
	 *            Shift)
	 */
	protected void showShortcutSelectionDialog(IResource resource, List<LaunchShortcutExtension> shortcuts, String mode, IStructuredSelection selection, boolean isShift) {
		LaunchShortcutSelectionDialog dialog = new LaunchShortcutSelectionDialog(shortcuts, resource, mode);
		if (dialog.open() == Window.OK) {
			Object[] result = dialog.getResult();
			if(result.length > 0) {
				LaunchShortcutExtension method = (LaunchShortcutExtension) result[0];
				if(method != null) {
					launchShortcut(selection, method, mode, isShift);
				}
			}
		}
	}
}
