/*****************************************************************************
 * Copyright (c) 2019 CEA LIST, and others.
 *
 * All rights reserved. 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:
 *   Nicolas FAUVERGUE (CEA LIST) nicolas.fauvergue@cea.fr - Initial API and implementation
 *
 *****************************************************************************/
package org.eclipse.papyrus.gitlight.compare.ui.internal.structuremergeviewer.groups;

import static com.google.common.base.Predicates.not;
import static com.google.common.collect.Collections2.filter;

import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.emf.common.util.ECollections;
import org.eclipse.emf.compare.Comparison;
import org.eclipse.emf.compare.Diff;
import org.eclipse.emf.compare.Match;
import org.eclipse.emf.compare.MatchResource;
import org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.groups.impl.BasicDifferenceGroupImpl;
import org.eclipse.emf.compare.rcp.ui.internal.structuremergeviewer.nodes.MatchNode;
import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide;
import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.AbstractDifferenceGroupProvider;
import org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroup;
import org.eclipse.emf.compare.scope.IComparisonScope;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.util.ECrossReferenceAdapter;
import org.eclipse.emf.edit.tree.TreeFactory;
import org.eclipse.emf.edit.tree.TreeNode;
import org.eclipse.papyrus.gitlight.compare.ui.contentmergeviewer.facet.PapyrusFacetContentProviderWrapper;
import org.eclipse.papyrus.gitlight.compare.ui.internal.context.PapyrusContextUtil;
import org.eclipse.papyrus.infra.viewpoints.policy.ViewPrototype;
import org.eclipse.papyrus.uml.tools.providers.SemanticUMLContentProvider;

/**
 * This implementation of a
 * {@link org.eclipse.emf.compare.rcp.ui.structuremergeviewer.groups.IDifferenceGroupProvider} will be used to
 * group the differences of Papyrus models.
 */
@SuppressWarnings("restriction")
public class PapyrusGroupProvider extends AbstractDifferenceGroupProvider {

	/**
	 * Predicate testing whether a {@link MatchResource} is a UML resource (file extension is .uml).
	 */
	private static final Predicate<? super MatchResource> IS_UML_RESOURCE = new Predicate<MatchResource>() {
		private final Predicate<Resource> isUML = PapyrusContextUtil.isUMLResource();

		public boolean apply(MatchResource input) {
			return input != null //
					&& (isUML.apply(input.getLeft()) || isUML.apply(input.getRight())
							|| isUML.apply(input.getOrigin()));
		}
	};

	/**
	 * Specialized {@link BasicDifferenceGroupImpl} for Papyrus models.
	 */
	public static class PapyrusDifferenceGroup extends BasicDifferenceGroupImpl {

		/** Map for retrieving the corresponding TreeNode of a model element. **/
		private Map<EObject, TreeNode> valueToMatchNode;

		/** Map for retrieving the context UML element of a notation (Diagram/Table/etc.). **/
		private HashMap<EObject, EObject> notationToContextualParent;

		/** A predicate testing whether a match matches notations (Diagrams/Tables/etc.). **/
		private final Predicate<Match> matchValueNotationPredicate = new Predicate<Match>() {
			public boolean apply(Match match) {
				EObject matchValue = getMatchValue(match);
				return (matchValue != null) && ViewPrototype.isViewObject(matchValue);
			}
		};

		/**
		 * Initializes me with my comparison and cross-referencer.
		 * 
		 * @param comparison
		 *            the comparison being presented
		 * @param crossReferenceAdapter
		 *            a cross-reference adapter to propagate down the tree
		 */
		public PapyrusDifferenceGroup(Comparison comparison, ECrossReferenceAdapter crossReferenceAdapter) {
			super(comparison, Predicates.<Diff> alwaysTrue(), crossReferenceAdapter);
			valueToMatchNode = new HashMap<>();
			notationToContextualParent = new HashMap<>();
			retrieveContextualNotationParents(MergeViewerSide.LEFT);
			retrieveContextualNotationParents(MergeViewerSide.RIGHT);
		}

		/**
		 * Makes use of the PapyrusFacetContentProviderWrapper to retrieve the contextual UML element for each
		 * notation of the Comparison.
		 * 
		 * @param side
		 *            Defines the comparison side for retrieving the elements
		 */
		private void retrieveContextualNotationParents(MergeViewerSide side) {
			ResourceSet resourceSet = getResourceSet(getComparison(), side);
			if (resourceSet != null) {
				SemanticUMLContentProvider contentProvider = new SemanticUMLContentProvider(resourceSet);
				try {
					for (Object root : contentProvider.getElements(null)) {
						retrieveNotationParents(root, contentProvider);
					}
				} finally {
					contentProvider.dispose();
				}
			}
		}

		/**
		 * Recursively traverses the UML mode tree and maps all notations and their contextual parent.
		 * 
		 * @param object
		 *            the child Object
		 * @param facetContentProviderWrapper
		 *            the {@link PapyrusFacetContentProviderWrapper}
		 */
		private void retrieveNotationParents(Object object, SemanticUMLContentProvider contentProvider) {
			Function<Object, EObject> asEObject = adapt(EObject.class);

			// These children are EMF Facet TreeObjects
			for (Object child : contentProvider.getChildren(object)) {
				// Get the encapsulated model object
				EObject eObjectChild = asEObject.apply(child);
				if (eObjectChild != null) {
					// This is a legitimate case
					EObject eObjectParent = asEObject.apply(object);
					if (eObjectParent != null && ViewPrototype.isViewObject(eObjectChild)) {
						if (!notationToContextualParent.containsKey(eObjectChild)) {
							notationToContextualParent.put(eObjectChild, eObjectParent);
						}
					}
					retrieveNotationParents(child, contentProvider);
				}
			}
		}

		static <T> Function<Object, T> adapt(final Class<T> adapterType) {
			return new Function<Object, T>() {
				public T apply(Object input) {
					if (adapterType.isInstance(input)) {
						return adapterType.cast(input);
					} else if (input instanceof IAdaptable) {
						return ((IAdaptable)input).getAdapter(adapterType);
					} else {
						return null;
					}
				}
			};
		}

		@Override
		protected List<TreeNode> buildMatchTrees() {
			final List<TreeNode> matchTrees = new ArrayList<TreeNode>();

			final Collection<Match> matches = getComparison().getMatches();

			/*
			 * Notation matches rely on information of other match trees for proper grouping (valueToMatchNode
			 * map needs to be populated ). So first all match trees for non-notation matches are built and
			 * the notation match sub trees are built separately in a second iteration.
			 */
			for (Match match : filter(matches, not(isMatchValueANotation()))) {
				MatchNode matchNode = buildTree(match);
				if (matchNode != null) {
					matchTrees.add(matchNode);
				}
			}

			// But, we still want to present all notation views first as in the Model Explorer
			List<TreeNode> nodesToSort = Lists.newArrayList();
			for (Match match : filter(matches, isMatchValueANotation())) {
				TreeNode notationNode = buildTree(match);
				if (notationNode != null) {
					TreeNode parentNode = retrieveParentNode(notationNode, getParent(getMatchValue(match)));
					parentNode.getChildren().add(notationNode);
					notationNode.setParent(parentNode);
					nodesToSort.add(parentNode); // This needs sorting
				}
			}

			if (!nodesToSort.isEmpty()) {
				Comparator<TreeNode> sortBy = treeNodeOrdering();
				for (TreeNode next : nodesToSort) {
					ECollections.sort(next.getChildren(), sortBy);
				}
			}

			return matchTrees;
		}

		/**
		 * Obtain a comparator for sorting tree nodes by kind:
		 * <ol>
		 * <li>diffs of the object represented by the parent node (its own details) should come before
		 * anything to do with child objects</li>
		 * <li>notation views (diagrams, tables, etc.)</li>
		 * <li>all other children</li>
		 * </ol>
		 * 
		 * @return the tree node comparator
		 */
		protected Comparator<TreeNode> treeNodeOrdering() {
			return new Comparator<TreeNode>() {
				public int compare(TreeNode o1, TreeNode o2) {
					int key1 = computeSortKey(o1);
					int key2 = computeSortKey(o2);
					return key1 - key2;
				}

				private int computeSortKey(TreeNode node) {
					EObject object = node.getData();
					if (object instanceof Diff) {
						// Diffs of the object should come before anything about children
						return -2;
					}

					if (object instanceof Match //
							&& isMatchValueANotation().apply((Match)object)) {

						// These come next
						return -1;
					}

					// Everything else follows
					return 0;
				}
			};
		}

		/**
		 * Creates a predicate for determining if the associated EObject of a Match is an instance of the
		 * given class.
		 * 
		 * @param clazz
		 *            the Class
		 * @return the created Predicate
		 */
		private Predicate<Match> isMatchValueANotation() {
			return matchValueNotationPredicate;
		}

		/**
		 * Creates a new TreeNode.
		 * 
		 * @param data
		 *            data object of the node
		 * @return created TreeNode
		 */
		private TreeNode createTreeNode(EObject data) {
			TreeNode node = TreeFactory.eINSTANCE.createTreeNode();
			node.setData(data);
			return node;
		}

		/**
		 * Determines the parent node of the given TreeNode. If the parent node doesn't exist yet the
		 * corresponding node and (sub) tree is created and merged into the match tree.
		 * 
		 * @param childNode
		 *            the child TreeNode
		 * @param parentObject
		 *            the data object of the parent node
		 * @return (new) parent TreeNode
		 */
		private TreeNode retrieveParentNode(TreeNode childNode, EObject parentObject) {
			TreeNode parentNode = getOrCreateParentNode(childNode, parentObject);
			if (!(parentNode instanceof MatchNode)) {
				// the parent node is a newly created node -> the corresponding subtree has to be created
				createSubTree(parentNode, getParent(parentObject));
			}
			return parentNode;

		}

		/**
		 * Retrieves the parent node of given TreeNode. If no matching node exists in the match tree a new
		 * node is created
		 * 
		 * @param childNode
		 *            the child TreeNode
		 * @param parentObject
		 *            (new) parent TreeNode
		 * @return (new) parent TreeNode
		 */
		private TreeNode getOrCreateParentNode(TreeNode childNode, EObject parentObject) {
			if (parentObject == null) {
				// we have no parent to add this childNode; this may happen if a notation has no context;
				// thus,
				// we add it as root node (childNode is the parent without any parent)
				return childNode;
			}

			TreeNode parentNode = valueToMatchNode.get(parentObject);
			if (parentNode == null) {
				parentNode = createTreeNode(parentObject);
			}

			childNode.setParent(parentNode);
			parentNode.getChildren().add(childNode);
			return parentNode;
		}

		/**
		 * Retrieves the contextual parent of the given EObject.
		 * 
		 * @param value
		 *            the child EObject
		 * @return parent EObject
		 */
		private EObject getParent(EObject value) {
			EObject result = notationToContextualParent.get(value);
			if (result == null && value != null) {
				result = value.eContainer();
			}
			return result;
		}

		/**
		 * Creates the subtree for the given tree node with a recursive bottom-up approach.
		 *
		 * @param treeNode
		 *            the TreeNode
		 * @param parentObject
		 *            the parent EObject
		 */
		private void createSubTree(TreeNode treeNode, EObject parentObject) {
			if (parentObject == null) {
				children.add(treeNode);
				return;
			}
			TreeNode parentNode = getOrCreateParentNode(treeNode, parentObject);
			treeNode.setParent(parentNode);
			parentNode.getChildren().add(treeNode);
			if (parentNode instanceof MatchNode) {
				return;
			}
			createSubTree(parentNode, getParent(parentObject));
		}

		@Override
		protected void populateMatchNode(MatchNode matchNode) {
			super.populateMatchNode(matchNode);
			if (!matchNode.getChildren().isEmpty()) {
				valueToMatchNode.put(getMatchValue(matchNode.getMatch()), matchNode);
			}
		}

		/**
		 * Returns the corresponding EObject for the given Match.
		 * 
		 * @param match
		 *            the Match
		 * @return the corresponding EObject
		 */
		private EObject getMatchValue(Match match) {
			if (match.getLeft() != null) {
				return match.getLeft();
			}
			if (match.getRight() != null) {
				return match.getRight();
			}
			return match.getOrigin();
		}

		/**
		 * Determines the object of the given match and side.
		 * 
		 * @param comparison
		 *            the {@link Comparison}.
		 * @param side
		 *            the {@link MergeViewerSide}.
		 * @return the determined {@link Object}, may be {@code null}.
		 */
		private ResourceSet getResourceSet(Comparison comparison, MergeViewerSide side) {
			for (MatchResource matchResource : comparison.getMatchedResources()) {
				Resource resource = getResource(matchResource, side);
				if (resource != null) {
					return resource.getResourceSet();
				}
			}
			return null;
		}

		/**
		 * Determines the resource of the given match and side.
		 * 
		 * @param matchResource
		 *            the {@link MatchResource}.
		 * @param side
		 *            the {@link MergeViewerSide}.
		 * @return the determined {@link Resource}, may be {@code null}.
		 */
		private Resource getResource(MatchResource matchResource, MergeViewerSide side) {
			if (side != null) {
				switch (side) {
					case LEFT:
						return matchResource.getLeft();
					case RIGHT:
						return matchResource.getRight();
					case ANCESTOR:
						return matchResource.getOrigin();
				}
			}
			return null;
		}

	}

	@Override
	protected Collection<? extends IDifferenceGroup> buildGroups(Comparison comparison) {
		PapyrusDifferenceGroup group = new PapyrusDifferenceGroup(getComparison(),
				getCrossReferenceAdapter());
		group.buildSubTree();
		return ImmutableList.of(group);
	}

	@Override
	public boolean isEnabled(IComparisonScope scope, Comparison comparison) {
		return super.isEnabled(scope, comparison) && PapyrusContextUtil.isPapyrusContext(comparison)
				&& hasAtLeastOneUMLResource(comparison);
	}

	/**
	 * Specifies whether the given comparison has at least one UML resource in its matched resources.
	 * 
	 * @param comparison
	 *            The comparison to test.
	 * @return <code>true</code> if it has at least one {@link MatchResource} of a UML resource,
	 *         <code>false</code> otherwise.
	 */
	private boolean hasAtLeastOneUMLResource(Comparison comparison) {
		return Iterables.any(comparison.getMatchedResources(), IS_UML_RESOURCE);
	}

}
