/*******************************************************************************
 * Copyright (c) 2006 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.ltk.ui.refactoring.model;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import org.eclipse.team.core.mapping.ISynchronizationContext;
import org.eclipse.team.core.mapping.ISynchronizationScope;
import org.eclipse.team.ui.mapping.MergeActionHandler;
import org.eclipse.team.ui.mapping.SynchronizationActionProvider;
import org.eclipse.team.ui.synchronize.ISynchronizePageConfiguration;

import org.eclipse.core.runtime.Assert;

import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.commands.IHandler;

import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.mapping.ResourceMapping;

import org.eclipse.ltk.core.refactoring.RefactoringDescriptor;
import org.eclipse.ltk.core.refactoring.RefactoringDescriptorProxy;
import org.eclipse.ltk.core.refactoring.history.RefactoringHistory;
import org.eclipse.ltk.core.refactoring.model.AbstractRefactoringDescriptorResourceMapping;
import org.eclipse.ltk.core.refactoring.model.AbstractRefactoringHistoryResourceMapping;

import org.eclipse.ltk.internal.core.refactoring.history.RefactoringDescriptorProxyAdapter;
import org.eclipse.ltk.internal.ui.refactoring.actions.AcceptRefactoringsAction;
import org.eclipse.ltk.internal.ui.refactoring.actions.RejectRefactoringsAction;

import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;

/**
 * Refactoring-aware synchronization action provider which contributes an action
 * to accept pending refactorings during team synchronization.
 * <p>
 * This action provider contributes an action for refactoring history objects.
 * Additionally, existing command handlers for the <code>Merge</code>,
 * <code>Mark As Merged</code> and <code>Overwrite</code> actions are
 * wrapped and automatically disabled for refactoring history objects.
 * </p>
 * <p>
 * Note: this class is intended to be extended by clients who need refactoring
 * support in a team synchronization viewer. It needs to be be registered with
 * the <code>org.eclipse.ui.navigator.navigatorContent</code> or
 * <code>org.eclipse.ui.navigator.viewer</code> extension points in order to
 * participate in the team synchronization viewers.
 * </p>
 * 
 * @see org.eclipse.team.ui.mapping.SynchronizationActionProvider
 * 
 * @since 3.2
 */
public class RefactoringSynchronizationActionProvider extends SynchronizationActionProvider {

	/** Delegate for refactoring action handlers */
	private final class RefactoringHandlerDelegate extends AbstractHandler {

		/** The delegate handler */
		private final IHandler fDelegateHandler;

		/**
		 * Creates a new synchronization handler delegate.
		 * 
		 * @param handler
		 *            the delegate handler
		 */
		public RefactoringHandlerDelegate(final IHandler handler) {
			Assert.isNotNull(handler);
			fDelegateHandler= handler;
		}

		/**
		 * {@inheritDoc}
		 */
		public void dispose() {
			fDelegateHandler.dispose();
			super.dispose();
		}

		/**
		 * {@inheritDoc}
		 */
		public Object execute(final ExecutionEvent event) throws ExecutionException {
			return fDelegateHandler.execute(event);
		}

		/**
		 * {@inheritDoc}
		 */
		public boolean isEnabled() {
			return !hasRefactorings(getSynchronizationContext(), getSynchronizePageConfiguration()) && fDelegateHandler.isEnabled();
		}
	}

	/**
	 * Gets the refactoring represented by the specified proxy.
	 * 
	 * @param scope
	 *            the synchronization scope
	 * @param proxy
	 *            the refactoring descriptor proxy
	 * @param set
	 *            the set of refactoring descriptor proxies
	 */
	private static void getRefactoring(final ISynchronizationScope scope, final RefactoringDescriptorProxy proxy, final Set set) {
		final ResourceMapping mapping= (ResourceMapping) proxy.getAdapter(ResourceMapping.class);
		if (mapping instanceof AbstractRefactoringDescriptorResourceMapping) {
			final AbstractRefactoringDescriptorResourceMapping extended= (AbstractRefactoringDescriptorResourceMapping) mapping;
			final IResource resource= extended.getResource();
			if (resource != null && scope.contains(resource))
				set.add(proxy);
		}
	}

	/**
	 * Returns the currently selected refactorings.
	 * 
	 * @param context
	 *            the synchronization context
	 * @param configuration
	 *            the synchronize page configuration
	 * @return the selected refactorings, or the empty array
	 */
	private static RefactoringDescriptorProxy[] getRefactorings(final ISynchronizationContext context, final ISynchronizePageConfiguration configuration) {
		Assert.isNotNull(context);
		Assert.isNotNull(configuration);
		final Set set= new HashSet();
		final ISelection selection= configuration.getSite().getSelectionProvider().getSelection();
		if (selection instanceof IStructuredSelection) {
			final IStructuredSelection structured= (IStructuredSelection) selection;
			if (!structured.isEmpty()) {
				final Object[] elements= structured.toArray();
				final ISynchronizationScope scope= context.getScope();
				for (int index= 0; index < elements.length; index++) {
					if (elements[index] instanceof RefactoringHistory) {
						getRefactorings(scope, (RefactoringHistory) elements[index], set);
					} else if (elements[index] instanceof RefactoringDescriptorProxy) {
						getRefactoring(scope, (RefactoringDescriptorProxy) elements[index], set);
					} else if (elements[index] instanceof RefactoringDescriptor) {
						getRefactoring(scope, new RefactoringDescriptorProxyAdapter(((RefactoringDescriptor) elements[index])), set);
					}
				}
			}
		}
		return (RefactoringDescriptorProxy[]) set.toArray(new RefactoringDescriptorProxy[set.size()]);
	}

	/**
	 * Gets the refactorings represented by the specified history.
	 * 
	 * @param scope
	 *            the synchronization scope
	 * @param history
	 *            the refactoring history
	 * @param set
	 *            the set of refactoring descriptor proxies
	 */
	private static void getRefactorings(final ISynchronizationScope scope, final RefactoringHistory history, final Set set) {
		final ResourceMapping mapping= (ResourceMapping) history.getAdapter(ResourceMapping.class);
		if (mapping instanceof AbstractRefactoringHistoryResourceMapping) {
			final AbstractRefactoringHistoryResourceMapping extended= (AbstractRefactoringHistoryResourceMapping) mapping;
			final IResource resource= extended.getResource();
			if (resource != null && scope.contains(resource))
				set.addAll(Arrays.asList(history.getDescriptors()));
		}
	}

	/**
	 * Is the specified refactoring in the scope?
	 * 
	 * @param scope
	 *            the synchronization scope
	 * @param proxy
	 *            the refactoring descriptor proxy
	 * @return <code>true</code> if the refactoring is in the scope,
	 *         <code>false</code> otherwise
	 */
	private static boolean hasRefactoring(final ISynchronizationScope scope, final RefactoringDescriptorProxy proxy) {
		final ResourceMapping mapping= (ResourceMapping) proxy.getAdapter(ResourceMapping.class);
		if (mapping instanceof AbstractRefactoringDescriptorResourceMapping) {
			final AbstractRefactoringDescriptorResourceMapping extended= (AbstractRefactoringDescriptorResourceMapping) mapping;
			final IResource resource= extended.getResource();
			if (resource != null)
				return scope.contains(resource);
		}
		return false;
	}

	/**
	 * Returns whether any refactorings from the given synchronization context
	 * are selected.
	 * 
	 * @param context
	 *            the synchronization context
	 * @param configuration
	 *            the synchronize page configuration
	 * @return <code>true</code> if any refactorings are selected,
	 *         <code>false</code> otherwise
	 */
	private static boolean hasRefactorings(final ISynchronizationContext context, final ISynchronizePageConfiguration configuration) {
		Assert.isNotNull(context);
		Assert.isNotNull(configuration);
		final ISelection selection= configuration.getSite().getSelectionProvider().getSelection();
		if (selection instanceof IStructuredSelection) {
			final IStructuredSelection structured= (IStructuredSelection) selection;
			if (!structured.isEmpty()) {
				final Object[] elements= structured.toArray();
				final ISynchronizationScope scope= context.getScope();
				for (int index= 0; index < elements.length; index++) {
					if (elements[index] instanceof RefactoringHistory) {
						return hasRefactorings(scope, (RefactoringHistory) elements[index]);
					} else if (elements[index] instanceof RefactoringDescriptorProxy) {
						return hasRefactoring(scope, (RefactoringDescriptorProxy) elements[index]);
					} else if (elements[index] instanceof RefactoringDescriptor) {
						return hasRefactoring(scope, new RefactoringDescriptorProxyAdapter((RefactoringDescriptor) elements[index]));
					}
				}
			}
		}
		return false;
	}

	/**
	 * Does the specified refactoring history contain any refactorings in the
	 * scope?
	 * 
	 * @param scope
	 *            the synchronization scope
	 * @param history
	 *            the refactoring history
	 * @return <code>true</code> if any refactorings are in the scope,
	 *         <code>false</code> otherwise
	 */
	private static boolean hasRefactorings(final ISynchronizationScope scope, final RefactoringHistory history) {
		final ResourceMapping mapping= (ResourceMapping) history.getAdapter(ResourceMapping.class);
		if (mapping instanceof AbstractRefactoringHistoryResourceMapping) {
			final AbstractRefactoringHistoryResourceMapping extended= (AbstractRefactoringHistoryResourceMapping) mapping;
			final IResource resource= extended.getResource();
			if (resource != null)
				return scope.contains(resource);
		}
		return false;
	}

	/**
	 * {@inheritDoc}
	 */
	public void fillContextMenu(final IMenuManager menu) {
		super.fillContextMenu(menu);
		if (isRefactoringElementSelected()) {
			final ISynchronizationContext context= getSynchronizationContext();
			final RefactoringDescriptorProxy[] proxies= getRefactorings(context, getSynchronizePageConfiguration());
			final AcceptRefactoringsAction accept= new AcceptRefactoringsAction(context, getExtensionSite().getViewSite().getShell());
			accept.setRefactoringDescriptors(proxies);
			menu.add(accept);
			final RejectRefactoringsAction reject= new RejectRefactoringsAction(context);
			reject.setRefactoringDescriptors(proxies);
			menu.add(reject);
		}
	}

	/**
	 * {@inheritDoc}
	 */
	protected void initialize() {
		super.initialize();
		final ISynchronizePageConfiguration configuration= getSynchronizePageConfiguration();
		registerHandler(MERGE_ACTION_ID, new RefactoringHandlerDelegate(MergeActionHandler.getDefaultHandler(MERGE_ACTION_ID, configuration)));
		registerHandler(OVERWRITE_ACTION_ID, new RefactoringHandlerDelegate(MergeActionHandler.getDefaultHandler(OVERWRITE_ACTION_ID, configuration)));
		registerHandler(MARK_AS_MERGE_ACTION_ID, new RefactoringHandlerDelegate(MergeActionHandler.getDefaultHandler(MARK_AS_MERGE_ACTION_ID, configuration)));
	}

	/**
	 * {@inheritDoc}
	 */
	protected void initializeOpenActions() {
		if (!hasRefactorings(getSynchronizationContext(), getSynchronizePageConfiguration()))
			super.initializeOpenActions();
	}

	private boolean isRefactoringElementSelected() {
		final ISelection selection= getContext().getSelection();
		if (selection instanceof IStructuredSelection) {
			final IStructuredSelection extended= (IStructuredSelection) selection;
			for (final Iterator iterator= extended.iterator(); iterator.hasNext();) {
				final Object element= iterator.next();
				if (element instanceof RefactoringDescriptorProxy || element instanceof RefactoringDescriptor || element instanceof RefactoringHistory) {
					return true;
				}
			}
		}
		return false;
	}
}