/*******************************************************************************
 * Copyright (c) 2006, 2008 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.core.databinding.observable.map;

import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.databinding.observable.Diffs;
import org.eclipse.core.databinding.observable.Realm;
import org.eclipse.core.databinding.observable.masterdetail.IObservableFactory;
import org.eclipse.core.databinding.observable.set.WritableSet;
import org.eclipse.core.runtime.Assert;

/**
 * A read-only observable map formed by the composition of two observable maps.
 * If map1 maps keys a:A to values b1:B, and map2 maps keys b2:B to values c:C,
 * the composite map maps keys a:A to values c:C. For example, map1 could map
 * Order objects to their corresponding Customer objects, and map2 could map
 * Customer objects to their "last name" property of type String. The composite
 * map of map1 and map2 would then map Order objects to their customers' last
 * names.
 * 
 * <p>
 * This class is thread safe. All state accessing methods must be invoked from
 * the {@link Realm#isCurrent() current realm}. Methods for adding and removing
 * listeners may be invoked from any thread.
 * </p>
 * 
 * @since 1.1
 * 
 */
public class CompositeMap extends ObservableMap {

	private Map valueToElements = new HashMap();

	// adds that need to go through the second map and thus will be picked up by
	// secondMapListener.
	private Set pendingAdds = new HashSet();

	// Removes that need to go through the second map and thus will be picked up
	// by
	// secondMapListener. Maps from value being removed to key being removed.
	private Map pendingRemoves = new HashMap();

	// Changes that need to go through the second map and thus will be picked up
	// by
	// secondMapListener. Maps from old value to new value and new value to old
	// value.
	private Map pendingChanges = new HashMap();

	private IMapChangeListener firstMapListener = new IMapChangeListener() {

		public void handleMapChange(MapChangeEvent event) {
			MapDiff diff = event.diff;
			Set rangeSetAdditions = new HashSet();
			Set rangeSetRemovals = new HashSet();
			final Set adds = new HashSet();
			final Set changes = new HashSet();
			final Set removes = new HashSet();
			final Map oldValues = new HashMap();

			for (Iterator it = diff.getAddedKeys().iterator(); it.hasNext();) {
				Object addedKey = it.next();
				Object newValue = diff.getNewValue(addedKey);
				addMapping(addedKey, newValue);
				if (!rangeSet.contains(newValue)) {
					pendingAdds.add(newValue);
					rangeSetAdditions.add(newValue);
				} else {
					adds.add(addedKey);
					wrappedMap.put(addedKey, secondMap.get(newValue));
				}
			}
			for (Iterator it = diff.getChangedKeys().iterator(); it.hasNext();) {
				Object changedKey = it.next();
				Object oldValue = diff.getOldValue(changedKey);
				Object newValue = diff.getNewValue(changedKey);
				boolean removed = removeMapping(changedKey, oldValue);
				addMapping(changedKey, newValue);
				boolean added = !rangeSet.contains(newValue);
				if (removed) {
					pendingRemoves.put(oldValue, changedKey);
					rangeSetRemovals.add(oldValue);
				}
				if (added) {
					pendingAdds.add(newValue);
					rangeSetAdditions.add(newValue);
				}
				if (added || removed) {
					pendingChanges.put(oldValue, newValue);
					pendingChanges.put(newValue, oldValue);
				} else {
					changes.add(changedKey);
					oldValues.put(changedKey, oldValue);
					wrappedMap.put(changedKey, newValue);
				}
			}
			for (Iterator it = diff.getRemovedKeys().iterator(); it.hasNext();) {
				Object removedKey = it.next();
				Object oldValue = diff.getOldValue(removedKey);
				if (removeMapping(removedKey, oldValue)) {
					pendingRemoves.put(oldValue, removedKey);
					rangeSetRemovals.add(oldValue);
				} else {
					removes.add(removedKey);
					oldValues.put(removedKey, secondMap.get(oldValue));
					wrappedMap.remove(removedKey);
				}
			}

			if (adds.size() > 0 || removes.size() > 0 || changes.size() > 0) {
				fireMapChange(new MapDiff() {

					public Set getAddedKeys() {
						return adds;
					}

					public Set getChangedKeys() {
						return changes;
					}

					public Object getNewValue(Object key) {
						return wrappedMap.get(key);
					}

					public Object getOldValue(Object key) {
						return oldValues.get(key);
					}

					public Set getRemovedKeys() {
						return removes;
					}
				});
			}

			if (rangeSetAdditions.size() > 0 || rangeSetRemovals.size() > 0) {
				rangeSet.addAndRemove(rangeSetAdditions, rangeSetRemovals);
			}
		}
	};

	private IMapChangeListener secondMapListener = new IMapChangeListener() {

		public void handleMapChange(MapChangeEvent event) {
			MapDiff diff = event.diff;
			final Set adds = new HashSet();
			final Set changes = new HashSet();
			final Set removes = new HashSet();
			final Map oldValues = new HashMap();
			final Map newValues = new HashMap();
			Set addedKeys = new HashSet(diff.getAddedKeys());
			Set removedKeys = new HashSet(diff.getRemovedKeys());

			for (Iterator it = addedKeys.iterator(); it.hasNext();) {
				Object addedKey = it.next();
				Set elements = getElementsForValue(addedKey);
				Object newValue = diff.getNewValue(addedKey);
				if (pendingChanges.containsKey(addedKey)) {
					Object oldKey = pendingChanges.remove(addedKey);
					Object oldValue;
					if (removedKeys.remove(oldKey)) {
						oldValue = diff.getOldValue(oldKey);
					} else {
						oldValue = secondMap.get(oldKey);
					}
					pendingChanges.remove(oldKey);
					pendingAdds.remove(addedKey);
					pendingRemoves.remove(oldKey);
					for (Iterator it2 = elements.iterator(); it2.hasNext();) {
						Object element = it2.next();
						changes.add(element);
						oldValues.put(element, oldValue);
						newValues.put(element, newValue);
						wrappedMap.put(element, newValue);
					}
				} else if (pendingAdds.remove(addedKey)) {
					for (Iterator it2 = elements.iterator(); it2.hasNext();) {
						Object element = it2.next();
						adds.add(element);
						newValues.put(element, newValue);
						wrappedMap.put(element, newValue);
					}
				} else {
					Assert.isTrue(false, "unexpected case"); //$NON-NLS-1$
				}
			}
			for (Iterator it = diff.getChangedKeys().iterator(); it.hasNext();) {
				Object changedKey = it.next();
				Set elements = getElementsForValue(changedKey);
				for (Iterator it2 = elements.iterator(); it2.hasNext();) {
					Object element = it2.next();
					changes.add(element);
					oldValues.put(element, diff.getOldValue(changedKey));
					Object newValue = diff.getNewValue(changedKey);
					newValues.put(element, newValue);
					wrappedMap.put(element, newValue);
				}
			}
			for (Iterator it = removedKeys.iterator(); it.hasNext();) {
				Object removedKey = it.next();
				Object element = pendingRemoves.remove(removedKey);
				if (element != null) {
					if (pendingChanges.containsKey(removedKey)) {
						Object newKey = pendingChanges.remove(removedKey);
						pendingChanges.remove(newKey);
						pendingAdds.remove(newKey);
						pendingRemoves.remove(removedKey);
						changes.add(element);
						oldValues.put(element, diff.getOldValue(removedKey));
						Object newValue = secondMap.get(newKey);
						newValues.put(element, newValue);
						wrappedMap.put(element, newValue);
					} else {
						removes.add(element);
						Object oldValue = diff.getOldValue(removedKey);
						oldValues.put(element, oldValue);
						wrappedMap.remove(element);
					}
				} else {
					changes.add(element);
				}
			}

			if (adds.size() > 0 || removes.size() > 0 || changes.size() > 0) {
				fireMapChange(new MapDiff() {

					public Set getAddedKeys() {
						return adds;
					}

					public Set getChangedKeys() {
						return changes;
					}

					public Object getNewValue(Object key) {
						return newValues.get(key);
					}

					public Object getOldValue(Object key) {
						return oldValues.get(key);
					}

					public Set getRemovedKeys() {
						return removes;
					}
				});
			}
		}
	};

	private IObservableMap firstMap;
	private IObservableMap secondMap;

	private static class WritableSetPlus extends WritableSet {
		void addAndRemove(Set additions, Set removals) {
			wrappedSet.removeAll(removals);
			wrappedSet.addAll(additions);
			fireSetChange(Diffs.createSetDiff(additions, removals));
		}
	}

	private WritableSetPlus rangeSet = new WritableSetPlus();

	/**
	 * Creates a new composite map. Because the key set of the second map is
	 * determined by the value set of the given observable map
	 * <code>firstMap</code>, it cannot be passed in as an argument. Instead,
	 * the second map will be created by calling
	 * <code>secondMapFactory.createObservable(valueSet())</code>.
	 * 
	 * @param firstMap
	 *            the first map
	 * @param secondMapFactory
	 *            a factory that creates the second map when given an observable
	 *            set representing the value set of <code>firstMap</code>.
	 */
	public CompositeMap(IObservableMap firstMap,
			IObservableFactory secondMapFactory) {
		super(firstMap.getRealm(), new HashMap());
		this.firstMap = firstMap;
		firstMap.addMapChangeListener(firstMapListener);
		for (Iterator it = firstMap.entrySet().iterator(); it.hasNext();) {
			Map.Entry entry = (Entry) it.next();
			addMapping(entry.getKey(), entry.getValue());
			rangeSet.add(entry.getValue());
		}
		this.secondMap = (IObservableMap) secondMapFactory
				.createObservable(rangeSet);
		secondMap.addMapChangeListener(secondMapListener);
		for (Iterator it = firstMap.entrySet().iterator(); it.hasNext();) {
			Map.Entry entry = (Entry) it.next();
			wrappedMap.put(entry.getKey(), secondMap.get(entry.getValue()));
		}
	}

	/**
	 * @param key
	 * @param value
	 */
	private void addMapping(Object key, Object value) {
		Object elementOrSet = valueToElements.get(value);
		if (elementOrSet == null) {
			valueToElements.put(value, key);
			return;
		}
		if (!(elementOrSet instanceof Set)) {
			elementOrSet = new HashSet(Collections.singleton(elementOrSet));
			valueToElements.put(value, elementOrSet);
		}
		Set set = (Set) elementOrSet;
		set.add(key);
	}

	/**
	 * @param key
	 * @param value
	 */
	private boolean removeMapping(Object key, Object value) {
		Object elementOrSet = valueToElements.get(value);
		if (elementOrSet instanceof Set) {
			Set set = (Set) elementOrSet;
			set.remove(key);
			if (set.size() == 0) {
				valueToElements.remove(value);
				return true;
			}
			return false;
		}
		valueToElements.remove(value);
		return true;
	}

	private Set getElementsForValue(Object value) {
		Object elementOrSet = valueToElements.get(value);
		if (elementOrSet instanceof Set) {
			return (Set) elementOrSet;
		}
		return elementOrSet == null ? Collections.EMPTY_SET : Collections
				.singleton(elementOrSet);
	}

	public synchronized void dispose() {
		super.dispose();
		firstMap.removeMapChangeListener(firstMapListener);
		firstMap = null;
		secondMap = null;
	}

}
