/*******************************************************************************
 * Copyright (c) 2004, 2019 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
 *     Mike Morearty - Bug 255310: Launching only gets the progress bar to 91%
 *******************************************************************************/
package org.eclipse.debug.core.model;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.IBreakpointManager;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.core.IStatusHandler;
import org.eclipse.debug.internal.core.DebugCoreMessages;
import org.eclipse.debug.internal.core.IInternalDebugCoreConstants;

import com.ibm.icu.text.MessageFormat;

/**
 * Default implementation of a launch configuration delegate. Provides
 * convenience methods for computing the build order of projects,
 * building projects, and searching for errors in the workspace. The
 * default pre-launch check prompts the user to launch in debug mode
 * if breakpoints are present in the workspace.
 * <p>
 * Clients implementing launch configuration delegates should subclass
 * this class.
 * </p>
 * @since 3.0
 */
public abstract class LaunchConfigurationDelegate implements ILaunchConfigurationDelegate2 {

	/**
	 * Constant to define debug.core for the status codes
	 *
	 * @since 3.2
	 */
	private static final String DEBUG_CORE = "org.eclipse.debug.core"; //$NON-NLS-1$

	/**
	 * Constant to define debug.ui for the status codes
	 *
	 * @since 3.2
	 */
	private static final String DEBUG_UI = "org.eclipse.debug.ui"; //$NON-NLS-1$

	/**
	 * Status code for which a UI prompter is registered.
	 */
	protected static final IStatus promptStatus = new Status(IStatus.INFO, DEBUG_UI, 200, IInternalDebugCoreConstants.EMPTY_STRING, null);

	/**
	 * Status code for which a prompter is registered to ask the user if they
	 * want to launch in debug mode when breakpoints are present.
	 */
	protected static final IStatus switchToDebugPromptStatus = new Status(IStatus.INFO, DEBUG_CORE, 201, IInternalDebugCoreConstants.EMPTY_STRING, null);

	/**
	 * Status code for which a prompter is registered to ask the user if the
	 * want to continue launch despite existing compile errors
	 */
	protected static final IStatus complileErrorPromptStatus = new Status(IStatus.INFO, DEBUG_CORE, 202, IInternalDebugCoreConstants.EMPTY_STRING, null);

	/**
	 * Status code for which a prompter will ask the user to save any/all of the dirty editors which have only to do
	 * with this launch (scoping them to the current launch/build)
	 *
	 * @since 3.2
	 */
	protected static final IStatus saveScopedDirtyEditors = new Status(IStatus.INFO, DEBUG_CORE, 222, IInternalDebugCoreConstants.EMPTY_STRING, null);

	/**
	 * Status code for which a prompter is registered to ask the user if the
	 * want to continue launch despite existing compile errors in specific
	 * projects. This enhances the 'compileErrorPromptStatus' by specifying
	 * which projects the errors exist in.
	 *
	 * @since 3.1
	 */
	protected static final IStatus complileErrorProjectPromptStatus = new Status(IStatus.INFO, DEBUG_CORE, 203, IInternalDebugCoreConstants.EMPTY_STRING, null);

	@Override
	public ILaunch getLaunch(ILaunchConfiguration configuration, String mode) throws CoreException {
		return null;
	}

	@Override
	public boolean buildForLaunch(ILaunchConfiguration configuration, String mode, IProgressMonitor monitor) throws CoreException {
		IProject[] projects = getBuildOrder(configuration, mode);
		if (projects == null) {
			return true;
		}
		buildProjects(projects, SubMonitor.convert(monitor, 1));
		return false;
	}

	/**
	 * Returns the projects to build before launching the given launch configuration
	 * or <code>null</code> if the entire workspace should be built incrementally.
	 * Subclasses should override as required.
	 *
	 * @param configuration the configuration being launched
	 * @param mode launch mode
	 * @return projects to build, in build order, or <code>null</code>
	 * @throws CoreException if an exception occurs
	 */
	protected IProject[] getBuildOrder(ILaunchConfiguration configuration, String mode) throws CoreException {
		return null;
	}

	/**
	 * Returns the set of projects to use when searching for errors or <code>null</code>
	 * if no search is to be done.
	 *
	 * @param configuration the configuration being launched
	 * @param mode launch mode
	 * @return a list of projects or <code>null</code>
	 * @throws CoreException if an exception occurs
	 */
	protected IProject[] getProjectsForProblemSearch(ILaunchConfiguration configuration, String mode) throws CoreException {
		return null;
	}

	@Override
	public boolean finalLaunchCheck(ILaunchConfiguration configuration, String mode, IProgressMonitor monitor) throws CoreException {
		monitor.beginTask("", 1); //$NON-NLS-1$
		try {
			IProject[] projects = getProjectsForProblemSearch(configuration, mode);
			if (projects == null) {
				return true; //continue launch
			}
			boolean continueLaunch = true;

			monitor.subTask(DebugCoreMessages.LaunchConfigurationDelegate_6);
			List<IAdaptable> errors = new ArrayList<>();
			for (IProject project : projects) {
				monitor.subTask(MessageFormat.format(DebugCoreMessages.LaunchConfigurationDelegate_7, new Object[] { project.getName() }));
				if (existsProblems(project)) {
					errors.add(project);
				}
			}
			if (!errors.isEmpty()) {
				errors.add(0, configuration);
				IStatusHandler prompter = DebugPlugin.getDefault().getStatusHandler(promptStatus);
				if (prompter != null) {
					continueLaunch = ((Boolean) prompter.handleStatus(complileErrorProjectPromptStatus, errors)).booleanValue();
				}
			}

			return continueLaunch;
		} finally {
			monitor.done();
		}
	}

	/*
	 * If launching in run mode, and the configuration supports debug mode,
	 * check if there are any breakpoints in the workspace, and ask the user if
	 * they'd rather launch in debug mode. <p> Since 3.2, this check also
	 * performs saving of resources before launching. </p>
	 * @see
	 * org.eclipse.debug.core.model.ILaunchConfigurationDelegate2#preLaunchCheck
	 * (org.eclipse.debug.core.ILaunchConfiguration, java.lang.String,
	 * org.eclipse.core.runtime.IProgressMonitor)
	 */
	@Override
	public boolean preLaunchCheck(ILaunchConfiguration configuration, String mode, IProgressMonitor monitor) throws CoreException {
		if (!saveBeforeLaunch(configuration, mode, monitor)) {
			return false;
		}
		if (mode.equals(ILaunchManager.RUN_MODE) && configuration.supportsMode(ILaunchManager.DEBUG_MODE)) {
			IBreakpoint[] breakpoints= getBreakpoints(configuration);
			if (breakpoints == null) {
				return true;
			}
			for (IBreakpoint breakpoint : breakpoints) {
				if (breakpoint.isEnabled()) {
					IStatusHandler prompter = DebugPlugin.getDefault().getStatusHandler(promptStatus);
					if (prompter != null) {
						boolean launchInDebugModeInstead = ((Boolean)prompter.handleStatus(switchToDebugPromptStatus, configuration)).booleanValue();
						if (launchInDebugModeInstead) {
							return false; //kill this launch
						}
					}
					// if no user prompt, or user says to continue (no need to check other breakpoints)
					return true;
				}
			}
		}
		// no enabled breakpoints... continue launch
		return true;
	}

	/**
	 * Performs the scoped saving of resources before launching and returns whether
	 * the launch should continue. By default, only resources contained within the projects
	 * which are part of the build scope are considered.
	 * <p>
	 * Subclasses may override this method if required.
	 * </p>
	 *
	 * @param configuration the configuration being launched
	 * @param mode the launch mode
	 * @param monitor progress monitor
	 * @return whether the launch should continue
	 * @throws CoreException if an exception occurs during the save
	 * @since 3.2
	 */
	protected boolean saveBeforeLaunch(ILaunchConfiguration configuration, String mode, IProgressMonitor monitor) throws CoreException {
		monitor.beginTask("", 1); //$NON-NLS-1$
		try {
			IStatusHandler prompter = DebugPlugin.getDefault().getStatusHandler(promptStatus);
			if(prompter != null) {
				//do save here and remove saving from DebugUIPlugin to avoid it 'trumping' this save
				IProject[] buildOrder = getBuildOrder(configuration, mode);
				if(!((Boolean)prompter.handleStatus(saveScopedDirtyEditors, new Object[]{configuration, buildOrder})).booleanValue()) {
					return false;
				}
			}
			return true;
		} finally {
			monitor.done();
		}
	}

	/**
	 * Returns the breakpoint collection that is relevant for this launch delegate.
	 * By default this is all the breakpoints registered with the Debug breakpoint manager.
	 *
	 * @param configuration the configuration to get associated breakpoints for
	 * @since 3.1
	 * @return the breakpoints that are relevant for this launch delegate
	 */
	protected IBreakpoint[] getBreakpoints(ILaunchConfiguration configuration) {
		IBreakpointManager breakpointManager = DebugPlugin.getDefault().getBreakpointManager();
		if (!breakpointManager.isEnabled()) {
			// no need to check breakpoints individually.
			return null;
		}
		return breakpointManager.getBreakpoints();
	}

	/**
	 * Returns an array of projects in their suggested build order
	 * containing all of the projects specified by <code>baseProjects</code>
	 * and all of their referenced projects.
	 *
	 * @param baseProjects a collection of projects
	 * @return an array of projects in their suggested build order
	 * containing all of the projects specified by <code>baseProjects</code>
	 * @throws CoreException if an error occurs while computing referenced
	 *  projects
	 */
	protected IProject[] computeReferencedBuildOrder(IProject[] baseProjects) throws CoreException {
		HashSet<IProject> unorderedProjects = new HashSet<>();
		for (IProject baseProject : baseProjects) {
			unorderedProjects.add(baseProject);
			addReferencedProjects(baseProject, unorderedProjects);
		}
		IProject[] projectSet = unorderedProjects.toArray(new IProject[unorderedProjects.size()]);
		return computeBuildOrder(projectSet);
	}


	/**
	 * Adds all projects referenced by <code>project</code> to the given
	 * set.
	 *
	 * @param project project
	 * @param references set to which referenced projects are added
	 * @throws CoreException if an error occurs while computing referenced
	 *  projects
	 */
	protected void addReferencedProjects(IProject project, Set<IProject> references) throws CoreException {
		if (project.isOpen()) {
			for (IProject refProject : project.getReferencedProjects()) {
				if (refProject.exists() && !references.contains(refProject)) {
					references.add(refProject);
					addReferencedProjects(refProject, references);
				}
			}
		}
	}

	/**
	 * Returns a list of projects in their suggested build order from the
	 * given unordered list of projects.
	 *
	 * @param projects the list of projects to sort into build order
	 * @return a new array containing all projects from <code>projects</code> sorted
	 *   according to their build order.
	 */
	protected IProject[] computeBuildOrder(IProject[] projects) {
		String[] orderedNames = ResourcesPlugin.getWorkspace().getDescription().getBuildOrder();
		if (orderedNames != null) {
			List<IProject> orderedProjects = new ArrayList<>(projects.length);
			//Projects may not be in the build order but should be built if selected
			List<IProject> unorderedProjects = new ArrayList<>(projects.length);
			Collections.addAll(unorderedProjects, projects);

			for (String projectName : orderedNames) {
				for (Iterator<IProject> iterator = unorderedProjects.iterator(); iterator.hasNext();) {
					IProject project = iterator.next();
					if (project.getName().equals(projectName)) {
						orderedProjects.add(project);
						iterator.remove();
						break;
					}
				}
			}
			//Add anything not specified before we return
			orderedProjects.addAll(unorderedProjects);
			return orderedProjects.toArray(new IProject[orderedProjects.size()]);
		}

		// Computing build order returned null, try the project prerequisite order
		IWorkspace.ProjectOrder po = ResourcesPlugin.getWorkspace().computeProjectOrder(projects);
		return po.projects;
	}

	/**
	 * Returns whether the given project contains any problem markers of the
	 * specified severity.
	 *
	 * @param proj the project to search
	 * @return whether the given project contains any problems that should
	 *  stop it from launching
	 * @throws CoreException if an error occurs while searching for
	 *  problem markers
	 */
	protected boolean existsProblems(IProject proj) throws CoreException {
		IMarker[] markers = proj.findMarkers(IMarker.PROBLEM, true, IResource.DEPTH_INFINITE);
		if (markers.length > 0) {
			for (IMarker marker : markers) {
				if (isLaunchProblem(marker)) {
					return true;
				}
			}
		}
		return false;
	}

	/**
	 * Returns whether the given problem should potentially abort the launch.
	 * By default if the problem has an error severity, the problem is considered
	 * a potential launch problem. Subclasses may override to specialize error
	 * detection.
	 *
	 * @param problemMarker candidate problem
	 * @return whether the given problem should potentially abort the launch
	 * @throws CoreException if any exceptions occur while accessing marker attributes
	 */
	protected boolean isLaunchProblem(IMarker problemMarker) throws CoreException {
		Integer severity = (Integer)problemMarker.getAttribute(IMarker.SEVERITY);
		if (severity != null) {
			return severity.intValue() >= IMarker.SEVERITY_ERROR;
		}

		return false;
	}

	/**
	 * Performs an incremental build on each of the given projects.
	 *
	 * @param projects projects to build
	 * @param monitor progress monitor
	 * @throws CoreException if an exception occurs while building
	 */
	protected void buildProjects(final IProject[] projects, IProgressMonitor monitor) throws CoreException {
		IWorkspaceRunnable build = new IWorkspaceRunnable(){
			@Override
			public void run(IProgressMonitor pm) throws CoreException {
				SubMonitor localmonitor = SubMonitor.convert(pm, DebugCoreMessages.LaunchConfigurationDelegate_scoped_incremental_build, projects.length);
				try {
					for (IProject project : projects) {
						if (localmonitor.isCanceled()) {
							throw new OperationCanceledException();
						}
						project.build(IncrementalProjectBuilder.INCREMENTAL_BUILD, localmonitor.newChild(1));
					}
				} finally {
					localmonitor.done();
				}
			}
		};
		ResourcesPlugin.getWorkspace().run(build, monitor);
	}
}
