/*******************************************************************************
 * Copyright (c) 2016, 2017 EclipseSource Muenchen GmbH 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:
 *     Stefan Dirix - initial API and implementation
 *     Philip Langer - introduce caching and improve selection
 *******************************************************************************/
package org.eclipse.papyrus.compare.diagram.ide.ui.contentmergeviewer;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;

import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.compare.ide.ui.internal.configuration.EMFCompareConfiguration;
import org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.tree.TreeContentMergeViewer;
import org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.tree.provider.MergeViewerItemProviderConfiguration;
import org.eclipse.emf.compare.rcp.ui.contentmergeviewer.accessor.ICompareAccessor;
import org.eclipse.emf.compare.rcp.ui.internal.mergeviewer.impl.AbstractMergeViewer;
import org.eclipse.emf.compare.rcp.ui.internal.mergeviewer.impl.AbstractTableOrTreeMergeViewer.ElementComparer;
import org.eclipse.emf.compare.rcp.ui.internal.mergeviewer.impl.TreeMergeViewer;
import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide;
import org.eclipse.emf.compare.rcp.ui.mergeviewer.item.IMergeViewerItem;
import org.eclipse.emf.compare.rcp.ui.mergeviewer.item.provider.IMergeViewerItemProviderConfiguration;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
import org.eclipse.jface.viewers.IBaseLabelProvider;
import org.eclipse.jface.viewers.IContentProvider;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.papyrus.compare.diagram.ide.ui.contentmergeviewer.facet.PapyrusFacetContentProviderWrapperAdapterFactory;
import org.eclipse.papyrus.compare.diagram.ide.ui.contentmergeviewer.provider.PapyrusTreeContentMergeViewerItemLabelProvider;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.widgets.Composite;

/**
 * Specialized Tree Content Merge Viewer for Papyrus.
 * 
 * @author Stefan Dirix
 */
@SuppressWarnings("restriction")
public class PapyrusTreeContentMergeViewer extends TreeContentMergeViewer {

	/**
	 * Since Papyrus trees could in theory be infinite, we need a maximum search level.
	 */
	private static final int MAX_SEARCH_LEVEL = 20;

	/**
	 * Map of objects to {@link PapyrusContentProviderMergeViewerItem Papyrus merge viewer items} used when
	 * changing the selection in order to find the merge viewer item to be selected when a specific object
	 * (model element or diff) is to be revealed.
	 */
	private Map<Object, IMergeViewerItem> cachedMapForSelection;

	/**
	 * A queue of computations for computing the content tree items in the {@linked #getLeftMergeViewer()
	 * right merge viewer}.
	 */
	private LinkedList<AbstractContentFunction> leftContentComputations;

	/**
	 * A queue of computations for computing the content tree items in the {@linked #getRightMergeViewer()
	 * left merge viewer}.
	 */
	private LinkedList<AbstractContentFunction> rightContentComputations;

	/**
	 * Constructor.
	 * 
	 * @param style
	 *            the style parameter
	 * @param bundle
	 *            the {@link ResourceBundle}
	 * @param parent
	 *            the {@link Composite} parent
	 * @param config
	 *            the {@link EMFCompareConfiguration}
	 */
	public PapyrusTreeContentMergeViewer(int style, ResourceBundle bundle, Composite parent,
			EMFCompareConfiguration config) {
		super(style, bundle, parent, config);
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.EMFCompareContentMergeViewer#createMergeViewer(org.eclipse.swt.widgets.Composite)
	 */
	@Override
	protected AbstractMergeViewer createMergeViewer(final Composite parent, final MergeViewerSide side) {
		final TreeMergeViewer mergeTreeViewer = new TreeMergeViewer(parent, side, this,
				getCompareConfiguration());
		final IContentProvider contentProvider = createMergeViewerContentProvider(side);
		mergeTreeViewer.setContentProvider(contentProvider);

		final IBaseLabelProvider labelProvider = new PapyrusTreeContentMergeViewerItemLabelProvider(
				getResourceBundle(), getAdapterFactory(), side);
		mergeTreeViewer.setLabelProvider(labelProvider);

		hookListeners(mergeTreeViewer);

		return mergeTreeViewer;
	}

	@Override
	protected IMergeViewerItemProviderConfiguration createMergeViewerItemProviderConfiguration(
			MergeViewerSide side) {
		ComposedAdapterFactory factory = new ComposedAdapterFactory(new AdapterFactory[] {
				new PapyrusFacetContentProviderWrapperAdapterFactory(), getAdapterFactory(), });
		return new MergeViewerItemProviderConfiguration(factory, getDifferenceGroupProvider(),
				getDifferenceFilterPredicate(), getCompareConfiguration().getComparison(), side);
	}

	/**
	 * Check whether the given input is an instance of {@link ICompareAccessor}.
	 * 
	 * @param input
	 *            the given input to check
	 * @return {@code true}, if the input is an instance of {@link ICompareAccessor}, {@code false} otherwise
	 */
	private static boolean isCompareAccessor(Object input) {
		return input instanceof ICompareAccessor;
	}

	/**
	 * Check whether the current input of the given side differs from the given one.
	 * 
	 * @param side
	 *            the side to be checked, either {@link MergeViewerSide#LEFT} or {@link MergeViewerSide#RIGHT}
	 * @param input
	 *            the input to check against
	 * @return {@code true}, if the input is different, {@code false} otherwise
	 */
	private boolean isDifferentInput(MergeViewerSide side, Object input) {
		TreeMergeViewer viewer = getMergeViewer(side);
		if (!isCompareAccessor(input) || !isCompareAccessor(viewer.getInput())) {
			return true;
		}
		ImmutableList<? extends IMergeViewerItem> inputItems = ICompareAccessor.class.cast(input).getItems();
		ImmutableList<? extends IMergeViewerItem> vieweritems = ICompareAccessor.class.cast(viewer.getInput())
				.getItems();
		if (inputItems.size() != vieweritems.size()) {
			return true;
		}
		ElementComparer comparer = new ElementComparer();
		for (int i = 0; i < vieweritems.size(); i++) {
			if (!comparer.equals(inputItems.get(i), vieweritems.get(i))) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Returns the {@link TreeMergeViewer} of the given side.
	 * 
	 * @param side
	 *            the side for which to return the {@link TreeMergeViewer}
	 * @return the {@link TreeMergeViewer} of the respective side
	 */
	public TreeMergeViewer getMergeViewer(MergeViewerSide side) {
		if (side == MergeViewerSide.LEFT) {
			return getLeftMergeViewer();
		} else if (side == MergeViewerSide.RIGHT) {
			return getRightMergeViewer();
		}
		return getAncestorMergeViewer();
	}

	@Override
	protected void updateContent(Object ancestor, Object left, Object right) {
		// Modify selection so it works with the Papyrus Merge Viewer Items

		// first check whether the input on any side has changed
		if (isDifferentInput(MergeViewerSide.LEFT, left) || isDifferentInput(MergeViewerSide.RIGHT, right)) {
			getAncestorMergeViewer().setInput(ancestor);
			getLeftMergeViewer().setInput(left);
			getRightMergeViewer().setInput(right);

			leftContentComputations = null;
			rightContentComputations = null;
			cachedMapForSelection = null;
		} else {
			getLeftMergeViewer().refresh();
			getRightMergeViewer().refresh();
		}

		IMergeViewerItem leftInitialItem = null;
		if (left instanceof ICompareAccessor) {
			leftInitialItem = ((ICompareAccessor)left).getInitialItem();
		}

		// Bug 458818: In some cases, the left initial item is null because
		// the item that should be selected has been deleted on the right
		// and this delete is part of a conflict
		if (leftInitialItem == null || leftInitialItem.getLeft() == null) {
			if (right instanceof ICompareAccessor) {
				IMergeViewerItem rightInitialItem = ((ICompareAccessor)right).getInitialItem();
				if (rightInitialItem == null) {
					getLeftMergeViewer().setSelection(StructuredSelection.EMPTY, true);
				} else {
					setSelection((ICompareAccessor)right);
				}
			} else {
				// Strange case: left is an ICompareAccessor but right is not?
				getLeftMergeViewer().setSelection(StructuredSelection.EMPTY, true);
			}
		} else {
			// others will synchronize on this one :)
			setSelection((ICompareAccessor)left);
		}
		redrawCenterControl();
	}

	/**
	 * Sets the selection according to the accessor.
	 * 
	 * @param accessor
	 *            The {@link ICompareAccessor} which contains the root tree elements and the initial
	 *            selection.
	 */
	private void setSelection(ICompareAccessor accessor) {
		// First try to set the initial item directly
		final IMergeViewerItem initialItem = accessor.getInitialItem();
		TreeMergeViewer viewer = getMergeViewer(initialItem.getSide());
		viewer.setSelection(new StructuredSelection(initialItem), true);

		// if that didn't work (empty selection), use cache to find correct merge viewer item
		if (viewer.getSelection().isEmpty()) {
			IMergeViewerItem itemToBeSelected = getItemToBeSelected(initialItem, viewer);
			if (itemToBeSelected != null) {
				viewer.setSelection(new StructuredSelection(itemToBeSelected), true);
			} else {
				viewer.setSelection(new StructuredSelection(), true);
			}
		}
	}

	/**
	 * Determines the item to select from the corresponding side viewer, given an input item.
	 * 
	 * @param item
	 *            the input item.
	 * @param viewer
	 *            the viewer in which to select the item.
	 * @return the item to be selected.
	 */
	private IMergeViewerItem getItemToBeSelected(IMergeViewerItem item, TreeMergeViewer viewer) {
		MergeViewerSide side = viewer.getSide();
		Object itemValue = item.getSideValue(side);
		IMergeViewerItem result;
		if (cachedMapForSelection == null) {
			cachedMapForSelection = Maps.newHashMap();
			result = null;
		} else {
			result = cachedMapForSelection.get(itemValue);
		}

		if (result == null && itemValue != null) {
			LinkedList<AbstractContentFunction> contentComputations;

			switch (side) {
				case LEFT:
					if (leftContentComputations == null) {
						leftContentComputations = Lists.newLinkedList();
						leftContentComputations.add(new ElementFunction(side, viewer, leftContentComputations,
								cachedMapForSelection));
					}
					contentComputations = leftContentComputations;
					break;

				case RIGHT:
					if (rightContentComputations == null) {
						rightContentComputations = Lists.newLinkedList();
						rightContentComputations.add(new ElementFunction(side, viewer,
								rightContentComputations, cachedMapForSelection));
					}
					contentComputations = rightContentComputations;
					break;

				default:
					throw new IllegalArgumentException();
			}

			Collection<Object> containers = getContainers(itemValue);
			if (!containers.isEmpty()) {
				// move necessary computations to the front
				List<AbstractContentFunction> containerComputations = extractComputations(contentComputations,
						containers);
				contentComputations.addAll(0, containerComputations);
			}

			result = computeItemToBeSelected(itemValue, containers, contentComputations);
		}

		return result;
	}

	/**
	 * Computes the item to be selected for the given item value, taking into account the containers, using
	 * the content computations.
	 * 
	 * @param itemValue
	 *            the item for which to base the selection.
	 * @param containers
	 *            the containers for that item.
	 * @param contentComputations
	 *            the computations for computing content.
	 * @return the item to be selected.
	 */
	private IMergeViewerItem computeItemToBeSelected(Object itemValue, Collection<Object> containers,
			LinkedList<AbstractContentFunction> contentComputations) {
		// We try to limit the amount of time we spend looking for selection.
		// Sometimes the object will not be present in the tree at all,
		// causing the whole tree to be visited.
		// So we keep track of which of the contains have not been visited,
		// removing any containers for which there is already a selection computed.
		IMergeViewerItem result = null;
		Collection<Object> unvistedContainers = Sets.newHashSet(containers);
		unvistedContainers.removeAll(cachedMapForSelection.keySet());
		long start = System.currentTimeMillis();
		while (!contentComputations.isEmpty()) {
			AbstractContentFunction contentFunction = contentComputations.removeFirst();

			// If we've visited all the containers and have been computing for more the 2 seconds,
			// stop looking and select the container instead.
			unvistedContainers.remove(contentFunction.getValue());
			if (unvistedContainers.isEmpty() && (System.currentTimeMillis() - start) > 2 * 1000) {
				break;
			}

			result = contentFunction.apply(itemValue, containers);
			if (result != null) {
				break;
			}
		}

		// If we haven't found the selection, try to find a selection for the nearest container.
		if (result == null) {
			for (Object container : containers) {
				result = cachedMapForSelection.get(container);
				if (result != null) {
					break;
				}
			}
		}

		return result;
	}

	@Override
	protected void handleDispose(DisposeEvent event) {
		if (cachedMapForSelection != null) {
			cachedMapForSelection = null;
		}

		super.handleDispose(event);
	}

	/**
	 * Extracts all content functions for the given objects from the computation list.
	 * 
	 * @param computations
	 *            computation list from which functions are extracted.
	 * @param values
	 *            values specifying which functions should be extracted.
	 * @return Non-null list of computations covering the given objects.
	 */
	private List<AbstractContentFunction> extractComputations(
			LinkedList<AbstractContentFunction> computations, Collection<Object> values) {
		List<AbstractContentFunction> extractedComputations = new ArrayList<>();
		Iterator<AbstractContentFunction> computationsIterator = computations.iterator();
		while (computationsIterator.hasNext()) {
			AbstractContentFunction contentFuction = computationsIterator.next();
			if (values.contains(contentFuction.getValue())) {
				computationsIterator.remove();
				extractedComputations.add(contentFuction);
			}
		}
		return extractedComputations;
	}

	/**
	 * Returns all EObject containers for the given value, if the given object is an EObject.
	 * 
	 * @param eObject
	 *            eObject value.
	 * @return Non-null collection of containers.
	 */
	private Collection<Object> getContainers(Object eObject) {
		Collection<Object> containers;
		if (eObject instanceof EObject) {
			containers = Sets.newLinkedHashSet();
			for (EObject container = ((EObject)eObject).eContainer(); container != null; container = container
					.eContainer()) {
				containers.add(container);
			}
		} else {
			containers = Collections.emptySet();
		}
		return containers;
	}

	/**
	 * A function for computing the items in the content tree induced by an item provider. Instances are
	 * managed in a {@link #contentComputations} queue and are processed to update the {@linked #selections
	 * selections} cache.
	 * 
	 * @see PapyrusTreeContentMergeViewer#getItemToBeSelected(IMergeViewerItem)
	 */
	private abstract static class AbstractContentFunction {
		/**
		 * The side for which the computation is being done.
		 */
		protected final MergeViewerSide side;

		/**
		 * The tree content provider which induces the content tree.
		 */
		protected final ITreeContentProvider provider;

		/**
		 * The queue of computations being managed.
		 * 
		 * @see PapyrusTreeContentMergeViewer#leftContentComputations
		 * @see PapyrusTreeContentMergeViewer#rightContentComputations
		 */
		protected final LinkedList<AbstractContentFunction> contentComputations;

		/**
		 * The selections being cached.
		 * 
		 * @see PapyrusTreeContentMergeViewer#cachedMapForSelection
		 */
		protected final Map<Object, IMergeViewerItem> selections;

		/**
		 * Creates and instance for a given side that induces content based on the given providers and manages
		 * the queue of content computations, updating the selections.
		 * 
		 * @param side
		 *            the side for which the content is being computed.
		 * @param provider
		 *            the provider used to induce content.
		 * @param contentComputations
		 *            the queue of computations being managed.
		 * @param selections
		 *            the selection cache being managed.
		 */
		protected AbstractContentFunction(MergeViewerSide side, ITreeContentProvider provider,
				LinkedList<AbstractContentFunction> contentComputations,
				Map<Object, IMergeViewerItem> selections) {
			this.side = side;
			this.provider = provider;
			this.contentComputations = contentComputations;
			this.selections = selections;
		}

		/**
		 * Computes new content and if any of the new content item matches the given value, returns the
		 * corresponding item from the side viewer. The {@link #contentComputations queue} is updated with
		 * functions for the new content items. Any new item with a value that matches one of the containers
		 * is placed at the front of the queue, rather than the back.
		 * 
		 * @param matchValue
		 *            the value to match.
		 * @param containers
		 *            the items that are of high priority to process first.
		 * @return the corresponding side viewer item for the match value, or null.
		 */
		public abstract IMergeViewerItem apply(Object matchValue, Collection<?> containers);

		/**
		 * Returns the value for which content will be computed.
		 * 
		 * @return the value for which content will be computed.
		 */
		public abstract Object getValue();

		/**
		 * A base helper method that does the computation needed by {@link #apply(Object, Collection)}.
		 * 
		 * @param matchValue
		 *            the value to be matched.
		 * @param containers
		 *            the items that are of high priority to process first.
		 * @param values
		 *            the new content items to be processed.
		 * @param depth
		 *            the current tree depth of the traversal.
		 * @return the corresponding side viewer item for the match value, or null.
		 */
		protected IMergeViewerItem apply(Object matchValue, Collection<?> containers, Object[] values,
				int depth) {
			IMergeViewerItem result = null;
			for (Object element : values) {
				if (element instanceof IMergeViewerItem) {
					final IMergeViewerItem item = (IMergeViewerItem)element;
					Object sideValue = item.getSideValue(side);

					// If we don't yet have a result, and the new value is equal to the matching value, then
					// cache it as the result.
					if (result == null) {
						if (sideValue != null && sideValue.equals(matchValue)) {
							result = item;
						}
					}

					// Create a new child function for the given item and add it to the front or the back of
					// the queue depending on whether the high priority containers include the item's side
					// value. So in general the content is build breadth first, but the subtree of the
					// containers is processed depth first.
					ChildFunction childFunction = new ChildFunction(side, provider, item, depth,
							contentComputations, selections);
					if (containers.contains(sideValue)) {
						contentComputations.addFirst(childFunction);
					} else {
						contentComputations.addLast(childFunction);

					}
				}
			}
			return result;
		}
	}

	/**
	 * A content function that computes the root elements of a side viewer.
	 */
	private static final class ElementFunction extends AbstractContentFunction {
		/**
		 * The input object of the side viewer.
		 */
		private final Object input;

		/**
		 * Creates and instance for a given side viewer that induces content based on the viewer's provider
		 * and manages the queue of content computations, updating the selections.
		 * 
		 * @param side
		 *            the side for which the content is being computed.
		 * @param viewer
		 *            the side viewer for which to induce content.
		 * @param contentComputations
		 *            the queue of computations being managed.
		 * @param selections
		 *            the selection cache being managed.
		 */
		private ElementFunction(MergeViewerSide side, TreeMergeViewer viewer,
				LinkedList<AbstractContentFunction> contentComputations,
				Map<Object, IMergeViewerItem> selections) {
			super(side, (ITreeContentProvider)viewer.getContentProvider(), contentComputations, selections);
			this.input = viewer.getInput();
		}

		@Override
		public Object getValue() {
			return input;
		}

		@Override
		public IMergeViewerItem apply(Object matchValue, Collection<?> containers) {
			return apply(matchValue, containers, provider.getElements(input), 0);
		}
	}

	/**
	 * A content function that computes the child elements of a side viewer.
	 */
	private static final class ChildFunction extends AbstractContentFunction {

		/**
		 * The item for which to induce child content.
		 */
		private final IMergeViewerItem item;

		/**
		 * The depth of the item.
		 */
		private final int depth;

		/**
		 * Creates and instance for a given side viewer's content provider that induces for the given item and
		 * the given depth and manages the queue of content computations, updating the selections.
		 * 
		 * @param side
		 *            the side for which the content is being computed.
		 * @param provider
		 *            the content provider of the side viewer.
		 * @param item
		 *            the item for which to induce child content.
		 * @param depth
		 *            the depth of the item.
		 * @param contentComputations
		 *            the queue of computations being managed.
		 * @param selections
		 *            the selection cache being managed.
		 */
		private ChildFunction(MergeViewerSide side, ITreeContentProvider provider, IMergeViewerItem item,
				int depth, LinkedList<AbstractContentFunction> contentComputations,
				Map<Object, IMergeViewerItem> selections) {
			super(side, provider, contentComputations, selections);
			this.item = item;
			this.depth = depth;

			Object value = item.getSideValue(side);
			if (value != null) {
				selections.put(value, item);
			}
		}

		@Override
		public Object getValue() {
			return item.getSideValue(side);
		}

		@Override
		public IMergeViewerItem apply(Object matchValue, Collection<?> containers) {
			if (depth == MAX_SEARCH_LEVEL) {
				return null;
			} else {
				return apply(matchValue, containers, provider.getChildren(item), depth + 1);
			}
		}
	}
}
