/*******************************************************************************
 * Copyright (c) 2017 EclipseSource Services 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:
 *     Philip Langer - initial API and implementation
 *******************************************************************************/
package org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.property;

import com.google.common.base.Predicate;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;

import java.util.Collections;
import java.util.List;
import java.util.Map;

import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.Notifier;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.compare.Diff;
import org.eclipse.emf.compare.Match;
import org.eclipse.emf.compare.ide.ui.internal.EMFCompareIDEUIMessages;
import org.eclipse.emf.compare.ide.ui.internal.configuration.EMFCompareConfiguration;
import org.eclipse.emf.compare.rcp.ui.internal.util.MergeViewerUtil;
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.structuremergeviewer.groups.IDifferenceGroupProvider;
import org.eclipse.emf.compare.utils.IEqualityHelper;
import org.eclipse.emf.compare.utils.MatchUtil;
import org.eclipse.emf.compare.utils.ReferenceUtil;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.edit.provider.AdapterFactoryItemDelegator;
import org.eclipse.emf.edit.provider.IItemFontProvider;
import org.eclipse.emf.edit.provider.IItemPropertyDescriptor;
import org.eclipse.emf.edit.provider.IItemPropertySource;
import org.eclipse.emf.edit.provider.ITableItemFontProvider;
import org.eclipse.emf.edit.provider.ITableItemLabelProvider;
import org.eclipse.emf.edit.provider.ItemProvider;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.widgets.TreeItem;

/**
 * An {@link ItemProvider} used to represent each item in the property tree. It implements
 * {@link IMergeViewerItem} to integrate with the underlying base framework. It is generally intended to work
 * in a {@link TreeViewer tree}, with two columns, a 'Property' column and a 'Value' column, supporting an
 * {@link #getColumnImage(Object, int) image} and {@link #getColumnText(Object, int) label} for each.
 */
@SuppressWarnings("deprecation")
abstract class PropertyItem extends ItemProvider implements ITableItemLabelProvider, ITableItemFontProvider, IMergeViewerItem.Container {

	/** This is the special category name for property descriptors without a category. */
	private static final String MISC_CATEGORY = EMFCompareIDEUIMessages
			.getString("PropertyContentMergeViewer.miscCategory.label"); //$NON-NLS-1$

	private static final String EXPERT_VIEW_FILTER_FLAG = "org.eclipse.ui.views.properties.expert"; //$NON-NLS-1$

	/**
	 * The configuration used by the property item. It is used to know the
	 * {@link EMFCompareConfiguration#getComparison() comparison} and to get
	 * {@link EMFCompareConfiguration#getBooleanProperty(String, boolean) properties}.
	 */
	private EMFCompareConfiguration configuration;

	/**
	 * The {@link #getSide() side} of this property item.
	 */
	private MergeViewerSide side;

	/**
	 * The property item corresponding to the ancestor.
	 */
	protected PropertyItem ancestor;

	/**
	 * The property item corresponding to the left.
	 */
	protected PropertyItem left;

	/**
	 * The property item corresponding to the right.
	 */
	protected PropertyItem right;

	/**
	 * Creates a root property item.
	 * <p>
	 * Builds a property item for the given object on the given side. This is used both to create a
	 * {@link #getRootItem() root} item and to build the children a property value that implements
	 * {@link IItemPropertySource}.
	 * </p>
	 * 
	 * @param configuration
	 *            the compare configuration of the root property item.
	 * @param object
	 *            the side object for the root property item.
	 * @param side
	 *            the side of this root property item.
	 * @return a new root property item.
	 */
	public static PropertyItem createPropertyItem(final EMFCompareConfiguration configuration,
			final Object object, final MergeViewerSide side) {
		PropertyItem rootItem;
		List<IItemPropertyDescriptor> propertyDescriptors;
		if (configuration.getAdapterFactory() != null) {
			final AdapterFactoryItemDelegator itemDelegator = new AdapterFactoryItemDelegator(
					configuration.getAdapterFactory());

			rootItem = new RootPropertyItem(configuration, itemDelegator.getImage(object),
					itemDelegator.getText(object), object, side);
			propertyDescriptors = getPropertyDescriptors(object, itemDelegator);
		} else {
			// We're currently disposing of the property content merge viewer
			rootItem = new RootPropertyItem(configuration, null, "", object, side); //$NON-NLS-1$
			propertyDescriptors = null;
		}
		populateRootPropertyItem(rootItem, propertyDescriptors, object, configuration, side);

		return rootItem;
	}

	private static List<IItemPropertyDescriptor> getPropertyDescriptors(final Object object,
			final AdapterFactoryItemDelegator itemDelegator) {
		List<IItemPropertyDescriptor> propertyDescriptors;
		if (object instanceof Resource) {
			// Special case for resources, because those generally have no property descriptors
			propertyDescriptors = Collections
					.singletonList(new ResourcePropertyDescriptor((Resource)object, itemDelegator));
		} else {
			propertyDescriptors = itemDelegator.getPropertyDescriptors(object);
		}
		return propertyDescriptors;
	}

	private static void populateRootPropertyItem(final PropertyItem rootItem,
			final List<IItemPropertyDescriptor> propertyDescriptors, final Object object,
			final EMFCompareConfiguration configuration, final MergeViewerSide side) {
		if (propertyDescriptors == null) {
			return;
		}

		Map<EStructuralFeature, Multimap<Object, Diff>> featureDiffs = buildFeatureToDiffMap(object,
				configuration);

		// A map from category name to a map from property name to the property descriptor item with
		// that name. These both use tree maps to sort the categories and the property descriptors.
		Map<String, Map<String, PropertyItem>> categories = Maps.newTreeMap();
		for (IItemPropertyDescriptor propertyDescriptor : propertyDescriptors) {
			addChildPropertyItem(categories, propertyDescriptor, object, configuration, featureDiffs, side);
		}

		// Compose the results into the children, do so with or without categories, as appropriate.
		EList<PropertyItem> children = rootItem.getPropertyItems();
		// If we're showing categories and there are categories, other than only the misc category...
		if (shouldShowCategories(configuration) && (categories.size() > 1
				|| categories.size() == 1 && categories.get(MISC_CATEGORY) == null)) {
			// Build a category item for each category, adding it to the children, and add the
			// property items as children of that category item.
			for (Map.Entry<String, Map<String, PropertyItem>> entry : categories.entrySet()) {
				PropertyItem categoryItem = new PropertyCategoryItem(configuration, entry.getKey(), side);
				children.add(categoryItem);
				categoryItem.getChildren().addAll(entry.getValue().values());
			}
		} else {
			// Otherwise, compose all the categories into a single map and use those sorted property
			// descriptor items as the children.
			Map<String, PropertyItem> sortedItems = Maps.newTreeMap();
			for (Map<String, PropertyItem> items : categories.values()) {
				sortedItems.putAll(items);
			}
			children.addAll(sortedItems.values());
		}
	}

	private static void addChildPropertyItem(Map<String, Map<String, PropertyItem>> categories,
			IItemPropertyDescriptor itemPropertyDescriptor, Object object,
			EMFCompareConfiguration configuration,
			Map<EStructuralFeature, Multimap<Object, Diff>> featureDiffs, MergeViewerSide side) {
		// If we're not showing advanced properties, skip the property descriptors flagged as
		// expert properties.
		if (!shouldShowAdvancedProperties(configuration)) {
			String[] filterFlags = itemPropertyDescriptor.getFilterFlags(object);
			if (filterFlags != null) {
				for (String filterFlag : filterFlags) {
					if (EXPERT_VIEW_FILTER_FLAG.equals(filterFlag)) {
						return;
					}
				}
			}
		}

		// Get the feature of the property fetch and its corresponding diffs multi-map.
		Object feature = itemPropertyDescriptor.getFeature(object);
		Multimap<Object, Diff> diffs = featureDiffs.remove(feature);
		PropertyItem childItem = new PropertyDescriptorItem(configuration, object, diffs,
				itemPropertyDescriptor, side);

		// Fetch the map for the category, creating one if necessary.
		String category = determineCategory(object, itemPropertyDescriptor);
		Map<String, PropertyItem> items = categories.get(category);
		if (items == null) {
			items = Maps.newTreeMap();
			categories.put(category, items);
		}

		// Put the item in the sorted map.
		items.put(itemPropertyDescriptor.getDisplayName(object), childItem);
	}

	private static String determineCategory(Object object, IItemPropertyDescriptor itemPropertyDescriptor) {
		// Determine the category, using misc if there isn't one.
		String category = itemPropertyDescriptor.getCategory(object);
		if (category == null) {
			category = MISC_CATEGORY;
		}
		return category;
	}

	private static boolean shouldShowCategories(EMFCompareConfiguration configuration) {
		return configuration.getBooleanProperty(PropertyContentMergeViewer.SHOW_CATEGORIES, true);
	}

	public static Match getMatch(EMFCompareConfiguration configuration, Object object) {
		Match match = null;
		if (object instanceof EObject) {
			EObject eObject = (EObject)object;
			match = configuration.getComparison().getMatch(eObject);
		}
		return match;
	}

	private static boolean shouldShowAdvancedProperties(EMFCompareConfiguration configuration) {
		return configuration.getBooleanProperty(PropertyContentMergeViewer.SHOW_ADVANCED_PROPERTIES, false);
	}

	/**
	 * Builds map from each feature to a multi-map of each side value to its corresponding diff.
	 * <p>
	 * We can only do this if object is an {@link EObject} and if <code>match</code> isn't <code>null</code>.
	 * </p>
	 * 
	 * @param object
	 *            The object to build the featureToDiff map for.
	 * @param match
	 *            the match of the object.
	 * @param comparison
	 *            The comparison.
	 * @return map from each feature to a multi-map of each side value to its corresponding diff.
	 */
	private static Map<EStructuralFeature, Multimap<Object, Diff>> buildFeatureToDiffMap(Object object,
			EMFCompareConfiguration configuration) {
		final Match match = getMatch(configuration, object);
		if (match == null || !(object instanceof EObject)) {
			return Maps.newHashMap();
		}

		final Map<EStructuralFeature, Multimap<Object, Diff>> featureDiffs = Maps.newHashMap();
		for (Diff diff : match.getDifferences()) {
			// If that diff affects a specific feature...
			EStructuralFeature eStructuralFeature = MergeViewerUtil.getAffectedFeature(diff);
			if (eStructuralFeature != null) {
				// Get the multi-map for that feature, creating a new one if necessary.
				Multimap<Object, Diff> diffs = featureDiffs.get(eStructuralFeature);
				if (diffs == null) {
					diffs = HashMultimap.create();
					featureDiffs.put(eStructuralFeature, diffs);
				}

				// Get the primary value of this diff and then iterate over the sides.
				Object value = MatchUtil.getValue(diff);
				for (MergeViewerSide valueSide : PropertyContentMergeViewer.MERGE_VIEWER_SIDES) {
					// If there is a corresponding side value for the match...
					EObject sideEObject = MergeViewerUtil.getEObject(match, valueSide);
					if (sideEObject != null) {
						// Get the corresponding value of that feature on that side.
						List<Object> sideValues = ReferenceUtil.getAsList(sideEObject, eStructuralFeature);
						// If the feature is multi-valued...
						if (eStructuralFeature.isMany()) {
							// Find the corresponding side-value of the value on those side values.
							Object sideValue = MergeViewerUtil.matchingValue(value,
									configuration.getComparison(), sideValues);
							if (sideValue != null) {
								diffs.put(sideValue, diff);
							}
						} else if (sideValues.isEmpty()) {
							// Otherwise, directly use what's typically the one value in the side values.
							diffs.put(null, diff);
						} else {
							diffs.put(sideValues.get(0), diff);
						}
					}
				}
			}
		}
		return featureDiffs;
	}

	/**
	 * Creates an instance of a property item.
	 * 
	 * @param configuration
	 *            the compare configuration.
	 * @param image
	 *            the image of this property item.
	 * @param text
	 *            the text of this property item.
	 * @param side
	 *            the side of this property item.
	 */
	public PropertyItem(EMFCompareConfiguration configuration, Object image, String text,
			MergeViewerSide side) {
		super(text, image);
		this.configuration = configuration;
		this.side = side;
		setSidePropertyItem(side, this);
	}

	/**
	 * Returns the corresponding property item for the specified side.
	 * 
	 * @param anySide
	 *            the side of the desired property item.
	 * @return the corresponding property item for the specified side.
	 */
	public PropertyItem getSide(MergeViewerSide anySide) {
		switch (anySide) {
			case ANCESTOR:
				return ancestor;
			case LEFT:
				return left;
			case RIGHT:
			default:
				return right;
		}
	}

	/**
	 * This is called on a {@link #createPropertyItem(EMFCompareConfiguration, Object, MergeViewerSide) root}
	 * item by {@link PropertyContentMergeViewer#buildPropertiesFromSides(Object, Object, Object)} once it has
	 * built all three sides.
	 * 
	 * @param newLeftSide
	 *            the corresponding left-side root property item.
	 * @param newRightSide
	 *            the corresponding right-side root property item.
	 */
	public void reconcile(PropertyItem newLeftSide, PropertyItem newRightSide) {
		associate(MergeViewerSide.LEFT, newLeftSide);
		associate(MergeViewerSide.RIGHT, newRightSide);

		if (newLeftSide != null) {
			newLeftSide.associate(MergeViewerSide.RIGHT, newRightSide);
			reconcile(newLeftSide.getPropertyItems());
		}

		if (newRightSide != null) {
			reconcile(newRightSide.getPropertyItems());
		}

		if (newLeftSide != null && newRightSide != null) {
			newLeftSide.reconcile(newRightSide.getPropertyItems());
		}

		for (PropertyItem propertyItem : getPropertyItems()) {
			propertyItem.reconcile();
		}

		if (newLeftSide != null) {
			for (PropertyItem propertyItem : newLeftSide.getPropertyItems()) {
				propertyItem.reconcile();
			}
		}

		if (newRightSide != null) {
			for (PropertyItem propertyItem : newRightSide.getPropertyItems()) {
				propertyItem.reconcile();
			}
		}
	}

	/**
	 * Set the appropriate bidirectional side associations.
	 * 
	 * @param otherSide
	 *            the side of that other property item.
	 * @param propertyItem
	 *            the other property item.
	 */
	private void associate(MergeViewerSide otherSide, PropertyItem propertyItem) {
		setSidePropertyItem(side, this);
		setSidePropertyItem(otherSide, propertyItem);
		if (propertyItem != null) {
			propertyItem.setSidePropertyItem(side, this);
			propertyItem.setSidePropertyItem(otherSide, propertyItem);
		}
	}

	/**
	 * Set the value of the appropriate side's field.
	 * 
	 * @param otherSide
	 *            the side to set.
	 * @param propertyItem
	 *            the value to which to set it.
	 */
	private void setSidePropertyItem(MergeViewerSide otherSide, PropertyItem propertyItem) {
		switch (otherSide) {
			case ANCESTOR:
				ancestor = propertyItem;
				break;
			case LEFT:
				left = propertyItem;
				break;
			case RIGHT:
				right = propertyItem;
				break;
		}
	}

	/**
	 * Reconcile's this side's properties against the other side property items.
	 * 
	 * @param otherPropertyItems
	 *            the other side's property items.
	 */
	private void reconcile(EList<PropertyItem> otherPropertyItems) {
		EList<PropertyItem> propertyItems = getPropertyItems();
		List<PropertyItem> remainingOtherPropertyItems = Lists.newArrayList(otherPropertyItems);
		for (PropertyItem propertyItem : propertyItems) {
			// This will associate the items, removing them once associated.
			propertyItem.findMatchingItem(remainingOtherPropertyItems, true);
		}
	}

	/**
	 * Reconcile the properties items of the sides against each other, and then recursively reconcile all the
	 * property items of each side.
	 */
	protected void reconcile() {
		switch (side) {
			case ANCESTOR:
				if (left != null) {
					reconcile(left.getPropertyItems());
				}
				if (right != null) {
					reconcile(right.getPropertyItems());
				}
				break;
			case LEFT:
				if (right != null) {
					left.reconcile(right.getPropertyItems());
				}
				break;
		}

		for (PropertyItem propertyItem : getPropertyItems()) {
			propertyItem.reconcile();
		}
	}

	/**
	 * Finds a matching item in the property items.
	 * 
	 * @param propertyItem
	 *            the item to find.
	 * @param propertyItems
	 *            the items in which to find it.
	 * @param associate
	 *            whether to associate the matching item and to remove it from the property items.
	 * @return the matching item.
	 */
	private PropertyItem findMatchingItem(List<? extends PropertyItem> propertyItems, boolean associate) {
		for (PropertyItem otherPropertyItem : propertyItems) {
			if (isMatchingItem(otherPropertyItem)) {
				if (associate) {
					associate(otherPropertyItem.side, otherPropertyItem);
					propertyItems.remove(otherPropertyItem);
				}
				return otherPropertyItem;
			}
		}
		return null;
	}

	/**
	 * Returns whether this property item matches the specified property item.
	 * 
	 * @param propertyItem
	 *            the property item against which to match.
	 * @return whether this property item matches the specified property item.
	 */
	protected abstract boolean isMatchingItem(PropertyItem propertyItem);

	/**
	 * Determines if the two values {@link IEqualityHelper#matchingValues(Object, Object) match} using the
	 * comparison's equality helper.
	 * 
	 * @param value1
	 *            the first value.
	 * @param value2
	 *            the second value.
	 * @return whether the two values match.
	 */
	protected boolean isMatchingValue(Object value1, Object value2) {
		IEqualityHelper equalityHelper = configuration.getComparison().getEqualityHelper();
		return equalityHelper.matchingValues(value1, value2);
	}

	/**
	 * Finds the corresponding property item of the specified property item somewhere within the receiver
	 * property item.
	 * 
	 * @param propertyItem
	 *            the property item to find.
	 * @return the corresponding property item or the deepest property item in the tree along the path of the
	 *         specified property item.
	 */
	public PropertyItem findItem(PropertyItem propertyItem) {
		PropertyItem propertyItemParent = propertyItem.getParent();
		if (propertyItemParent == null) {
			return this;
		} else {
			PropertyItem foundParent = findItem(propertyItemParent);

			PropertyItem findMatchingItem = propertyItem.findMatchingItem(foundParent.getPropertyItems(),
					false);

			if (findMatchingItem == null) {
				return this;
			} else {
				return findMatchingItem;
			}
		}
	}

	/**
	 * Returns the children, which must be property items.
	 * 
	 * @return the children.
	 */
	@SuppressWarnings("unchecked")
	public EList<PropertyItem> getPropertyItems() {
		return (EList<PropertyItem>)(EList<?>)children;
	}

	protected boolean isModified() {
		return false;
	}

	/**
	 * Returns the parent, which must be a property item.
	 * 
	 * @return the parent.
	 */
	@Override
	public PropertyItem getParent() {
		return (PropertyItem)super.getParent();
	}

	/**
	 * Returns the primary object of this property item.
	 * 
	 * @return the primary object of this property item.
	 */
	protected abstract Object getObject();

	/**
	 * Returns the root property item.
	 * 
	 * @return the root property item.
	 */
	public PropertyItem getRootItem() {
		PropertyItem rootItem = this;
		while (rootItem.getParent() != null) {
			rootItem = rootItem.getParent();
		}
		return rootItem;
	}

	/**
	 * This must be called when the item property descriptor is expanded and collapsed. For lists it's
	 * designed to hide the property image and property text while the list is expanded, showing it again when
	 * it's collapsed.
	 * 
	 * @param treeItem
	 *            the item being expanded or collapsed.
	 * @param expanded
	 *            whether the item is expanded as opposite to collapsed.
	 */
	public void update(TreeItem treeItem, boolean expanded) {
	}

	/**
	 * Returns the text for the value column of the property item.
	 * 
	 * @return the text for the value column of the property item.
	 */
	protected String getPropertyText() {
		return ""; //$NON-NLS-1$
	}

	/**
	 * Returns the image for the value column of the property item.
	 * 
	 * @return the image for the value column of the property item.
	 */
	protected Object getPropertyImage() {
		return null;
	}

	/**
	 * Returns the text for the property column or value column.
	 * 
	 * @param object
	 *            the object which is generally ignored.
	 * @param columnIndex
	 *            either {@code 0} or {@code 1}, for the property column or value column respectively.
	 * @return the text for the property column or value column.
	 */
	public String getColumnText(Object object, int columnIndex) {
		if (columnIndex == 0) {
			return getText(object);
		} else {
			return getPropertyText();
		}
	}

	/**
	 * Returns the image for the property column or value column.
	 * 
	 * @param object
	 *            the object which is generally ignored.
	 * @param columnIndex
	 *            either {@code 0} or {@code 1}, for the property column or value column respectively.
	 * @return the image for the property column or value column.
	 */
	public Object getColumnImage(Object object, int columnIndex) {
		if (columnIndex == 0) {
			return getImage(object);
		} else {
			return getPropertyImage();
		}
	}

	/**
	 * Returns the font for the property column or value column. {@link #isModified() Modified} property items
	 * will be shown in bold font.
	 * 
	 * @param object
	 *            the object, which is ignored.
	 * @param columnIndex
	 *            either {@code 0} or {@code 1}, for the property column or value column respectively.
	 * @return the font for the property column or value column.
	 */
	public Object getFont(Object object, int columnIndex) {
		if (isModified()) {
			return IItemFontProvider.BOLD_FONT;
		} else {
			return null;
		}
	}

	/**
	 * Returns the diff associated with this property item.
	 * 
	 * @return the diff associated with this property item.
	 */
	@Override
	public Diff getDiff() {
		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	public Object getLeft() {
		if (left != null) {
			return left.getObject();
		}
		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	public Object getRight() {
		if (right != null) {
			return right.getObject();
		}
		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	public Object getAncestor() {
		if (ancestor != null) {
			return ancestor.getObject();
		}
		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	public Object getSideValue(MergeViewerSide anySide) {
		switch (anySide) {
			case ANCESTOR:
				return getAncestor();
			case LEFT:
				return getLeft();
			case RIGHT:
			default:
				return getRight();
		}
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public MergeViewerSide getSide() {
		return side;
	}

	/**
	 * {@inheritDoc}
	 */
	public boolean isInsertionPoint() {
		return false;
	}

	/**
	 * {@inheritDoc}
	 */
	public void notifyChanged(Notification notification) {
	}

	/**
	 * {@inheritDoc}
	 */
	public Notifier getTarget() {
		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	public void setTarget(Notifier newTarget) {
	}

	/**
	 * {@inheritDoc}
	 */
	public boolean isAdapterForType(Object type) {
		return false;
	}

	/**
	 * {@inheritDoc}
	 */
	public boolean hasChildren(IDifferenceGroupProvider group, Predicate<? super EObject> predicate) {
		return false;
	}

	/**
	 * {@inheritDoc}
	 */
	public IMergeViewerItem[] getChildren(IDifferenceGroupProvider group,
			Predicate<? super EObject> predicate) {
		return null;
	}

	public EMFCompareConfiguration getConfiguration() {
		return configuration;
	}
}
