/*******************************************************************************
 * Copyright (c) 2000, 2017 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
 *******************************************************************************/
package org.eclipse.team.internal.ui.actions;

import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceStatus;
import org.eclipse.core.resources.mapping.ResourceMapping;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.team.core.RepositoryProvider;
import org.eclipse.team.core.TeamException;
import org.eclipse.team.internal.core.TeamPlugin;
import org.eclipse.team.internal.ui.TeamUIMessages;
import org.eclipse.team.internal.ui.TeamUIPlugin;
import org.eclipse.team.internal.ui.Utils;
import org.eclipse.ui.IActionDelegate2;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IObjectActionDelegate;
import org.eclipse.ui.IPartListener2;
import org.eclipse.ui.ISelectionListener;
import org.eclipse.ui.ISources;
import org.eclipse.ui.IViewActionDelegate;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchPartReference;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.IWorkbenchWindowActionDelegate;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.handlers.HandlerUtil;
import org.eclipse.ui.ide.ResourceUtil;

/**
 * The abstract superclass of all Team actions. This class contains some convenience
 * methods for getting selected objects and mapping selected objects to their
 * providers.
 *
 * Team providers may subclass this class when creating their actions.
 * Team providers may also instantiate or subclass any of the
 * subclasses of TeamAction provided in this package.
 */
public abstract class TeamAction extends AbstractHandler implements IObjectActionDelegate, IViewActionDelegate, IWorkbenchWindowActionDelegate, IActionDelegate2 {
	// The current selection
	private IStructuredSelection selection;

	// The shell, required for the progress dialog
	private Shell shell;

	// Constants for determining the type of progress. Subclasses may
	// pass one of these values to the run method.
	public final static int PROGRESS_DIALOG = 1;
	public final static int PROGRESS_BUSYCURSOR = 2;

	private IWorkbenchPart targetPart;
	private IWorkbenchWindow window;
	private IPartListener2 targetPartListener = new IPartListener2() {
		@Override
		public void partActivated(IWorkbenchPartReference partRef) {
		}

		@Override
		public void partBroughtToTop(IWorkbenchPartReference partRef) {
		}

		@Override
		public void partClosed(IWorkbenchPartReference partRef) {
			if (targetPart == partRef.getPart(false)) {
				targetPart = null;
			}
		}

		@Override
		public void partDeactivated(IWorkbenchPartReference partRef) {
		}

		@Override
		public void partHidden(IWorkbenchPartReference partRef) {
		}

		@Override
		public void partInputChanged(IWorkbenchPartReference partRef) {
		}

		@Override
		public void partOpened(IWorkbenchPartReference partRef) {
		}

		@Override
		public void partVisible(IWorkbenchPartReference partRef) {
		}
	};

	private ISelectionListener selectionListener = (part, selection) -> {
		if(selection instanceof IStructuredSelection)
			TeamAction.this.selection = (IStructuredSelection)selection;
	};

	/**
	 * Creates an array of the given class type containing all the
	 * objects in the selection that adapt to the given class.
	 *
	 * @param selection
	 * @param c
	 * @return the selected adaptables
	 */
	@SuppressWarnings("unchecked")
	public static <T> T[] getSelectedAdaptables(ISelection selection, Class<T> c) {
		ArrayList<T> result = null;
		if (selection != null && !selection.isEmpty()) {
			result = new ArrayList<>();
			Iterator elements = ((IStructuredSelection) selection).iterator();
			while (elements.hasNext()) {
				T adapter = getAdapter(elements.next(), c);
				if (c.isInstance(adapter)) {
					result.add(adapter);
				}
			}
		}
		if (result != null && !result.isEmpty()) {
			return result.toArray((T[]) Array.newInstance(c, result.size()));
		}
		return (T[]) Array.newInstance(c, 0);
	}

	/**
	 * Find the object associated with the given object when it is adapted to
	 * the provided class. Null is returned if the given object does not adapt
	 * to the given class
	 *
	 * @param adaptable
	 * @param c
	 * @return Object
	 */
	@SuppressWarnings("unchecked")
	public static <T> T getAdapter(Object adaptable, Class<T> c) {
		if (c.isInstance(adaptable)) {
			return (T) adaptable;
		}
		if (adaptable instanceof IAdaptable) {
			IAdaptable a = (IAdaptable) adaptable;
			T adapter = a.getAdapter(c);
			if (c.isInstance(adapter)) {
				return adapter;
			}
		}
		return null;
	}

	/**
	 * Returns the selected projects.
	 *
	 * @return the selected projects
	 */
	protected IProject[] getSelectedProjects() {
		IResource[] selectedResources = getSelectedResources();
		if (selectedResources.length == 0) return new IProject[0];
		ArrayList<IProject> projects = new ArrayList<>();
		for (int i = 0; i < selectedResources.length; i++) {
			IResource resource = selectedResources[i];
			if (resource.getType() == IResource.PROJECT) {
				projects.add((IProject) resource);
			}
		}
		return projects.toArray(new IProject[projects.size()]);
	}

	/**
	 * Returns an array of the given class type c that contains all
	 * instances of c that are either contained in the selection or
	 * are adapted from objects contained in the selection.
	 *
	 * @param c
	 * @return the selection adapted to the given class
	 */
	protected <T> T[] getAdaptedSelection(Class<T> c) {
		return getSelectedAdaptables(selection, c);
	}

	/**
	 * Returns the selected resources.
	 *
	 * @return the selected resources
	 */
	protected IResource[] getSelectedResources() {
		return Utils.getContributedResources(getSelection().toArray());
	}

	protected IStructuredSelection getSelection() {
		if (selection == null)
			selection = StructuredSelection.EMPTY;
		return selection;
	}

	/**
	 * Return the selected resource mappins that contain resources in
	 * projects that are associated with a repository of the given id.
	 * @param providerId the repository provider id
	 * @return the resource mappings that contain resources associated with the given provider
	 */
	protected ResourceMapping[] getSelectedResourceMappings(String providerId) {
		Object[] elements = getSelection().toArray();
		ArrayList<ResourceMapping> providerMappings = new ArrayList<>();
		for (int i = 0; i < elements.length; i++) {
			Object object = elements[i];
			Object adapted = getResourceMapping(object);
			if (adapted instanceof ResourceMapping) {
				ResourceMapping mapping = (ResourceMapping) adapted;
				if (providerId == null || isMappedToProvider(mapping, providerId)) {
					providerMappings.add(mapping);
				}
			}
		}
		return providerMappings.toArray(new ResourceMapping[providerMappings.size()]);
	}

	private Object getResourceMapping(Object object) {
		if (object instanceof ResourceMapping)
			return object;
		return Utils.getResourceMapping(object);
	}

	private boolean isMappedToProvider(ResourceMapping element, String providerId) {
		IProject[] projects = element.getProjects();
		for (int k = 0; k < projects.length; k++) {
			IProject project = projects[k];
			RepositoryProvider provider = RepositoryProvider.getProvider(project);
			if (provider != null && provider.getID().equals(providerId)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Convenience method for getting the current shell.
	 *
	 * @return the shell
	 */
	protected Shell getShell() {
		if (shell != null) {
			return shell;
		} else if (targetPart != null) {
			return targetPart.getSite().getShell();
		} else if (window != null) {
			return window.getShell();
		} else {
			IWorkbench workbench = TeamUIPlugin.getPlugin().getWorkbench();
			if (workbench == null) return null;
			IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
			if (window == null) return null;
			return window.getShell();
		}
	}
	/**
	 * Convenience method for running an operation with progress and
	 * error feedback.
	 *
	 * @param runnable  the runnable which executes the operation
	 * @param problemMessage  the message to display in the case of errors
	 * @param progressKind  one of PROGRESS_BUSYCURSOR or PROGRESS_DIALOG
	 */
	final protected void run(final IRunnableWithProgress runnable, final String problemMessage, int progressKind) {
		final Exception[] exceptions = new Exception[] {null};
		switch (progressKind) {
			case PROGRESS_BUSYCURSOR :
				BusyIndicator.showWhile(Display.getCurrent(), () -> {
					try {
						runnable.run(new NullProgressMonitor());
					} catch (InvocationTargetException e1) {
						exceptions[0] = e1;
					} catch (InterruptedException e2) {
						exceptions[0] = null;
					}
				});
				break;
			default :
			case PROGRESS_DIALOG :
				try {
					new ProgressMonitorDialog(getShell()).run(true, true, runnable);
				} catch (InvocationTargetException e) {
					exceptions[0] = e;
				} catch (InterruptedException e) {
					exceptions[0] = null;
				}
				break;
		}
		if (exceptions[0] != null) {
			handle(exceptions[0], null, problemMessage);
		}
	}

	/*
	 * Method declared on IActionDelegate.
	 */
	@Override
	public void selectionChanged(IAction action, ISelection selection) {
		if (selection instanceof IStructuredSelection) {
			this.selection = (IStructuredSelection) selection;
			if (action != null) {
				setActionEnablement(action);
			}
		}
	}

	/**
	 * Method invoked from <code>selectionChanged(IAction, ISelection)</code>
	 * to set the enablement status of the action. The instance variable
	 * <code>selection</code> will contain the latest selection so the methods
	 * <code>getSelectedResources()</code> and <code>getSelectedProjects()</code>
	 * will provide the proper objects.
	 *
	 * This method can be overridden by subclasses but should not be invoked by them.
	 */
	protected void setActionEnablement(IAction action) {
		action.setEnabled(isEnabled());
	}

	/**
	 * If an exception occurs during enablement testing, this method is invoked
	 * to determine if the action should be enabled or not.
	 * @param exception the exception
	 * @return whether the action should be enabled or not
	 */
	protected boolean isEnabledForException(TeamException exception) {
		if (exception.getStatus().getCode() == IResourceStatus.OUT_OF_SYNC_LOCAL) {
			// Enable the action to allow the user to discover the problem
			return true;
		}
		// We should not open a dialog when determining menu enablement so log it instead
		TeamPlugin.log(exception);
		return false;
	}

	/*
	 * Method declared on IObjectActionDelegate.
	 */
	@Override
	public void setActivePart(IAction action, IWorkbenchPart targetPart) {
		if(targetPart != null) {
			this.shell = targetPart.getSite().getShell();
			this.targetPart = targetPart;
		}
	}
	/**
	 * Shows the given errors to the user.
	 *
	 * @param exception  the status containing the error
	 * @param title  the title of the error dialog
	 * @param message  the message for the error dialog
	 */
	protected void handle(Exception exception, String title, String message) {
		Utils.handleError(getShell(), exception, title, message);
	}

	/**
	 * Convenience method that maps the given resources to their providers.
	 * The returned Hashtable has keys which are ITeamProviders, and values
	 * which are Lists of IResources that are shared with that provider.
	 *
	 * @return a hashtable mapping providers to their resources
	 */
	protected Hashtable<RepositoryProvider, List<IResource>> getProviderMapping(IResource[] resources) {
		Hashtable<RepositoryProvider, List<IResource>> result = new Hashtable<>();
		for (int i = 0; i < resources.length; i++) {
			RepositoryProvider provider = RepositoryProvider.getProvider(resources[i].getProject());
			List<IResource> list = result.get(provider);
			if (list == null) {
				list = new ArrayList<>();
				result.put(provider, list);
			}
			list.add(resources[i]);
		}
		return result;
	}

	/**
	 * @return IWorkbenchPart
	 */
	protected IWorkbenchPart getTargetPart() {
		if(targetPart == null) {
			IWorkbenchPage  page = TeamUIPlugin.getActivePage();
			if (page != null) {
				targetPart = page.getActivePart();
			}
		}
		return targetPart;

	}

	/**
	 * Return the path that was active when the menu item was selected.
	 * @return IWorkbenchPage
	 */
	protected IWorkbenchPage getTargetPage() {
		if (getTargetPart() == null) return TeamUIPlugin.getActivePage();
		return getTargetPart().getSite().getPage();
	}

	/**
	 * Show the view with the given ID in the perspective from which the action
	 * was executed. Returns null if the view is not registered.
	 *
	 * @param viewId
	 * @return IViewPart
	 */
	protected IViewPart showView(String viewId) {
		try {
			return getTargetPage().showView(viewId);
		} catch (PartInitException pe) {
			return null;
		}
	}

	@Override
	public void init(IViewPart view) {
		if(view != null) {
			this.shell = view.getSite().getShell();
			this.targetPart = view;
		}
	}

	@Override
	public void init(IWorkbenchWindow window) {
		this.window = window;
		this.shell = window.getShell();
		window.getSelectionService().addPostSelectionListener(selectionListener);
		window.getActivePage().addPartListener(targetPartListener);
	}

	public IWorkbenchWindow getWindow() {
		return window;
	}

	@Override
	public void dispose() {
		super.dispose();
		if(window != null) {
			window.getSelectionService().removePostSelectionListener(selectionListener);
			if (window.getActivePage() != null) {
				window.getActivePage().removePartListener(targetPartListener);
			}
			targetPartListener = null;
		}
		// Don't hold on to anything when we are disposed to prevent memory leaks (see bug 195521)
		selection = null;
		window = null;
		targetPart = null;
		shell = null;
	}

	/**
	 * Actions must override to do their work.
	 */
	protected abstract void execute(IAction action)
			throws InvocationTargetException, InterruptedException;

	/**
	 * This method is called by the platform UI framework when a command is run for
	 * which this action is the handler. The handler doesn't have an explicit context, for
	 * example unlike a view, editor, or workbench window actions, they are not initialized
	 * with a part. As a result when the action is run it will use the selection service
	 * to determine to elements on which to perform the action.
	 * <p>
	 * CVS actions should ensure that they can run without a proxy action. Meaning that
	 * <code>selectionChanged</code> and <code>run</code> should support passing
	 * <code>null</code> as the IAction parameter.
	 * </p>
	 * @throws ExecutionException
	 */
	@Override
	public Object execute(ExecutionEvent event) throws ExecutionException {
		IWorkbenchWindow activeWorkbenchWindow = HandlerUtil.getActiveWorkbenchWindow(event);
		if (activeWorkbenchWindow != null) {
			ISelection selection = HandlerUtil.getCurrentSelection(event);
			if (selection != null) {
				IWorkbenchPart part = HandlerUtil.getActivePart(event);
				try {
					execute(activeWorkbenchWindow,  part, selection);
				} catch (InvocationTargetException e) {
					throw new ExecutionException(TeamUIMessages.TeamAction_errorTitle, e);
				} catch (InterruptedException e) {
					// Operation was canceled. Ignore
				}
			}
		}
		return null;
	}

	private void execute(IWorkbenchWindow activeWorkbenchWindow,
			IWorkbenchPart part, ISelection selection)
			throws InvocationTargetException, InterruptedException {
		// If the action is run from within an editor, try and find the
		// file for the given editor.
		if (part != null && part instanceof IEditorPart) {
			IEditorInput input = ((IEditorPart) part).getEditorInput();
			IFile file = ResourceUtil.getFile(input);
			if (file != null) {
				selectionChanged((IAction) null, new StructuredSelection(file));
			}
		} else {
			// Fallback is to prime the action with the selection
			selectionChanged((IAction) null, selection);
		}
		// Safe guard to ensure that the action is only run when enabled.
		if (isEnabled()) {
			execute((IAction) null);
		} else {
			MessageDialog.openInformation(activeWorkbenchWindow.getShell(),
					TeamUIMessages.TeamAction_handlerNotEnabledTitle,
					TeamUIMessages.TeamAction_handlerNotEnabledMessage);
		}
	}

	/**
	 * Common run method for all Team actions.
	 */
	@Override
	public void run(IAction action) {
		try {
			execute(action);
		} catch (InvocationTargetException e) {
			// Handle the exception and any accumulated errors
			handle(e);
		} catch (InterruptedException e) {
			// Operation was canceled. Ignore.
		}
	}

	/**
	 * This method can be overridden by subclasses but should not be invoked by
	 * them.
	 *
	 * @param e
	 *            Exception to handle
	 */
	protected void handle(Exception e) {
		handle(e, TeamUIMessages.TeamAction_errorTitle, null);
	}

	/**
	 * The <code>TeamAction</code> implementation of this
	 * <code>IActionDelegate2</code> method does nothing. Subclasses may
	 * reimplement.
	 */
	@Override
	public void init(IAction action) {
	}

	/**
	 * The <code>TeamAction</code> implementation of this
	 * <code>IActionDelegate2</code> method redirects to the <code>run</code>
	 * method. Subclasses may reimplement.
	 */
	@Override
	final public void runWithEvent(IAction action, Event event) {
		run(action);
	}

	@Override
	public void setEnabled(Object evaluationContext) {
		IWorkbenchWindow activeWorkbenchWindow = (IWorkbenchWindow) HandlerUtil
				.getVariable(evaluationContext,
						ISources.ACTIVE_WORKBENCH_WINDOW_NAME);
		if (activeWorkbenchWindow != null) {
			ISelection selection = (ISelection) HandlerUtil.getVariable(
					evaluationContext, ISources.ACTIVE_CURRENT_SELECTION_NAME);
			if (selection == null) {
				selection = StructuredSelection.EMPTY;
			}
			IWorkbenchPart part = (IWorkbenchPart) HandlerUtil.getVariable(
					evaluationContext, ISources.ACTIVE_PART_NAME);
			updateSelection(part, selection);
		}
	}

	private void updateSelection(IWorkbenchPart part, ISelection selection) {
		// If the action is run from within an editor, try and find the
		// file for the given editor.
		setActivePart(null, part);
		if (part != null && part instanceof IEditorPart) {
			IEditorInput input = ((IEditorPart) part).getEditorInput();
			IFile file = ResourceUtil.getFile(input);
			if (file != null) {
				selectionChanged((IAction) null, new StructuredSelection(file));
			}
		} else {
			// Fallback is to prime the action with the selection
			selectionChanged((IAction) null, selection);
		}
	}

}
