/*******************************************************************************
 * Copyright (c) 2010, 2011 Oracle. 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:
 *     Oracle - initial API and implementation
 ******************************************************************************/
package org.eclipse.jpt.jaxb.core.internal;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.Vector;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jpt.common.core.internal.utility.jdt.JDTModifiedDeclaration.Adapter;
import org.eclipse.jpt.common.utility.internal.CollectionTools;
import org.eclipse.jpt.common.utility.internal.Tools;
import org.eclipse.jpt.common.utility.internal.iterables.ListIterable;
import org.eclipse.jpt.common.utility.internal.iterables.LiveCloneIterable;
import org.eclipse.jpt.common.utility.internal.iterables.LiveCloneListIterable;
import org.eclipse.jpt.common.utility.internal.model.AbstractModel;
import org.eclipse.jpt.common.utility.internal.model.AspectChangeSupport;
import org.eclipse.jpt.common.utility.internal.model.ChangeSupport;
import org.eclipse.jpt.jaxb.core.JaxbFactory;
import org.eclipse.jpt.jaxb.core.JaxbFile;
import org.eclipse.jpt.jaxb.core.JaxbNode;
import org.eclipse.jpt.jaxb.core.JaxbProject;
import org.eclipse.jpt.jaxb.core.context.JaxbContextNode;
import org.eclipse.jpt.jaxb.core.platform.JaxbPlatform;

/**
 * Some common Dali behavior:<ul>
 * <li>containment hierarchy
 * <li>Eclipse adaptable
 * <li>update triggers
 * </ul>
 */
public abstract class AbstractJaxbNode
	extends AbstractModel
	implements JaxbNode
{
	private final JaxbNode parent;


	// ********** constructor/initialization **********

	protected AbstractJaxbNode(JaxbNode parent) {
		super();
		this.checkParent(parent);
		this.parent = parent;
	}

	protected void checkParent(JaxbNode p) {
		if (p == null) {
			if (this.requiresParent()) {
				throw new IllegalArgumentException("'parent' cannot be null"); //$NON-NLS-1$
			}
		} else {
			if (this.forbidsParent()) {
				throw new IllegalArgumentException("'parent' must be null"); //$NON-NLS-1$
			}
		}
	}

	protected boolean requiresParent() {
		return true;
	}

	protected boolean forbidsParent() {
		return ! this.requiresParent();  // assume 'parent' is not optional
	}

	@Override
	protected ChangeSupport buildChangeSupport() {
		return new AspectChangeSupport(this, this.buildChangeSupportListener());
	}

	protected AspectChangeSupport.Listener buildChangeSupportListener() {
		return new AspectChangeSupport.Listener() {
			public void aspectChanged(String aspectName) {
				AbstractJaxbNode.this.aspectChanged(aspectName);
			}
		};
	}


	// ********** IAdaptable implementation **********

	@SuppressWarnings("rawtypes")
	public Object getAdapter(Class adapter) {
		return Platform.getAdapterManager().getAdapter(this, adapter);
	}


	// ********** JaxbNode implementation **********

	public JaxbNode getParent() {
		return this.parent;
	}

	public IResource getResource() {
		return this.parent.getResource();
	}

	public JaxbProject getJaxbProject() {
		return this.parent.getJaxbProject();
	}


	// ********** convenience methods **********

	protected JaxbPlatform getPlatform() {
		return this.getJaxbProject().getPlatform();
	}

//	protected JaxbPlatform.Version getJaxbPlatformVersion() {
//		return this.getJaxbPlatform().getJaxbPlatformVersion();
//	}

	protected JaxbFactory getFactory() {
		return this.getPlatform().getFactory();
	}

	protected JaxbFile getJaxbFile(IFile file) {
		return this.getJaxbProject().getJaxbFile(file);
	}


	// ********** CallbackChangeSupport.Listener support **********

	protected void aspectChanged(String aspectName) {
		if (this.aspectTriggersUpdate(aspectName)) {
//			String msg = Thread.currentThread() + " aspect change: " + this + ": " + aspectName;
//			System.out.println(msg);
//			new Exception(msg).printStackTrace(System.out);
			this.stateChanged();
		}
	}

	private boolean aspectTriggersUpdate(String aspectName) {
		return ! this.aspectDoesNotTriggerUpdate(aspectName);
	}

	protected boolean aspectDoesNotTriggerUpdate(String aspectName) {
		// ignore state changes so we don't get a stack overflow :-)
		// (and we don't use state changes except here)
		return (aspectName == null) ||
				this.nonUpdateAspectNames().contains(aspectName);
	}

	protected final Set<String> nonUpdateAspectNames() {
		synchronized (nonUpdateAspectNameSets) {
			HashSet<String> nonUpdateAspectNames = nonUpdateAspectNameSets.get(this.getClass());
			if (nonUpdateAspectNames == null) {
				nonUpdateAspectNames = new HashSet<String>();
				this.addNonUpdateAspectNamesTo(nonUpdateAspectNames);
				nonUpdateAspectNameSets.put(this.getClass(), nonUpdateAspectNames);
			}
			return nonUpdateAspectNames;
		}
	}

	private static final HashMap<Class<? extends AbstractJaxbNode>, HashSet<String>> nonUpdateAspectNameSets = new HashMap<Class<? extends AbstractJaxbNode>, HashSet<String>>();

	protected void addNonUpdateAspectNamesTo(@SuppressWarnings("unused") Set<String> nonUpdateAspectNames) {
	// when you override this method, don't forget to include:
	//	super.addNonUpdateAspectNamesTo(nonUpdateAspectNames);
	}

	public void stateChanged() {
		this.fireStateChanged();
		if (this.parent != null) {
			this.parent.stateChanged();
		}
	}


	/**
	 * Adapter used to synchronize a context collection container with its corresponding
	 * resource container.
	 * @param <C> the type of context elements
	 * @param <R> the type of resource elements
	 */
	protected abstract class CollectionContainer<C, R> {

		protected final Vector<C> contextElements = new Vector<C>();

		protected CollectionContainer() {
			super();
			this.initializeContextElements();
		}

		/**
		 * Return the container's current set of resource elements.
		 * These are what the context elements will be synchronized to.
		 */
		protected abstract Iterable<R> getResourceElements();

		/**
		 * Return the resource element corresponding to the specified context
		 * element.
		 */
		protected abstract R getResourceElement(C contextElement);

		/**
		 * Build and return a context element for the given resource element
		 */
		protected abstract C buildContextElement(R resourceElement);

		/**
		 * Return the property name for event notification when the collection is changed.
		 */
		protected abstract String getContextElementsPropertyName();

		protected void initializeContextElements() {
			for (R resourceElement : this.getResourceElements()) {
				this.contextElements.add(this.buildContextElement(resourceElement));
			}
		}

		/**
		 * Return an Iterable of the context elements
		 */
		public Iterable<C> getContextElements() {
			return new LiveCloneIterable<C>(this.contextElements);
		}

		/**
		 * Return the size of the context elements collection
		 */
		public int getContextElementsSize() {
			return this.contextElements.size();
		}

		/**
		 * Add a context element for the specified resource element at the
		 * specified index.
		 */
		public C addContextElement(int index, R resourceElement) {
			return this.addContextElement_(index, this.buildContextElement(resourceElement));
		}

		/**
		 * Add the specified context element to the collection ignoring
		 * the specified index as we only have a collection
		 */
		protected C addContextElement_(@SuppressWarnings("unused") int index, C contextElement) {
			AbstractJaxbNode.this.addItemToCollection(contextElement, this.contextElements, this.getContextElementsPropertyName());
			return contextElement;
		}

		/**
		 * Remove the specified context element from the container.
		 */
		public void removeContextElement(C element) {
			AbstractJaxbNode.this.removeItemFromCollection(element, this.contextElements, this.getContextElementsPropertyName());
		}

		@SuppressWarnings("unused") 
		protected void moveContextElement(int index, C element) {
			//no-op, not a list
		}
	}

	/**
	 * Adapter used to synchronize a context collection container with its corresponding
	 * resource container.
	 * @param <C> the type of context elements
	 * @param <R> the type of resource elements
	 */
	protected abstract class ContextCollectionContainer<C extends JaxbContextNode, R> extends CollectionContainer<C, R> {

		protected ContextCollectionContainer() {
			super();
		}

		/**
		 * Using the specified adapter, synchronize a context container with its
		 * corresponding resource container: moving, removing, and adding elements
		 * as necessary.
		 * <p>
		 * We can do this because:<ul>
		 * <li>the XML translators will <em>move</em> the EMF elements when
		 * appropriate (as opposed to simply rebuilding them in place).
		 * <li>the Java resource model will re-use existing annotations when
		 * appropriate (as opposed to simply rebuilding them in place).
		 * </ul>
		 */
		public void synchronizeWithResourceModel() {
			sync(true);  // true = sync
		}

		/**
		 * @see #synchronizeWithResourceModel(Adapter)
		 */
		public void update() {
			sync(false);  // false = update
		}

		/**
		 * The specified <code>sync</code> flag controls whether any surviving
		 * context nodes are either <em>synchronized</em> (<code>true</code>) or
		 * <em>updated</em> (<code>false</code>).
		 */
		protected void sync(boolean sync) {
			HashSet<C> contextElements = CollectionTools.set(this.getContextElements());
			int resourceIndex = 0;

			for (R resourceElement : this.getResourceElements()) {
				boolean match = false;
				for (Iterator<C> stream = contextElements.iterator(); stream.hasNext(); ) {
					C contextElement = stream.next();
					if (Tools.valuesAreEqual(this.getResourceElement(contextElement), resourceElement)) {
						// we don't know the source index because the element has been moved by previously moved elements
						this.moveContextElement(resourceIndex, contextElement);
						stream.remove();
						if (sync) {
							contextElement.synchronizeWithResourceModel();
						} else {
							contextElement.update();
						}
						match = true;
						break;
					}
				}
				if ( ! match) {
					// added elements are sync'ed during construction or will be
					// updated during the next "update" (which is triggered by
					// their addition to the model)
					this.addContextElement(resourceIndex, resourceElement);
				}
				resourceIndex++;
			}
			// remove any leftover context elements
			for (C contextElement : contextElements) {
				this.removeContextElement(contextElement);
			}
		}
	}

	/**
	 * Adapter used to synchronize a context list container with its corresponding
	 * resource container.
	 * @param <C> the type of context elements
	 * @param <R> the type of resource elements
	 */
	protected abstract class ListContainer<C, R>
		extends CollectionContainer<C, R> {

		protected ListContainer() {
			super();
		}

		@Override
		public ListIterable<C> getContextElements() {
			return new LiveCloneListIterable<C>(this.contextElements);
		}

		@Override
		protected abstract ListIterable<R> getResourceElements();

		/**
		 * Return the index of the specified context element.
		 */
		public int indexOfContextElement(C contextElement) {
			return this.contextElements.indexOf(contextElement);
		}

		public C contextElementAt(int index) {
			return this.contextElements.elementAt(index);
		}

		/**
		 * Add a context element for the specified resource element at the
		 * specified index.
		 */
		@Override
		protected C addContextElement_(int index, C contextElement) {
			AbstractJaxbNode.this.addItemToList(index, contextElement, this.contextElements, this.getContextElementsPropertyName());
			return contextElement;
		}

		/**
		 * Move the context element at the specified target index to the 
		 * specified source index.
		 */
		public void moveContextElement(int targetIndex, int sourceIndex) {
			this.moveContextElement(targetIndex, this.contextElements.get(sourceIndex));
		}

		/**
		 * Move the specified context element to the specified index.
		 */
		@Override
		public void moveContextElement(int index, C element) {
			AbstractJaxbNode.this.moveItemInList(index, element, this.contextElements, this.getContextElementsPropertyName());
		}

		/**
		 * Remove the context element at the specified index from the container.
		 */
		public void removeContextElement(int index) {
			AbstractJaxbNode.this.removeItemFromList(index, this.contextElements, this.getContextElementsPropertyName());
		}

		public void synchronizeWithResourceModel() {
			ListIterable<R> resourceElements = getResourceElements();
			
			int index = 0;
			for (R resourceElement : resourceElements) {
				if (this.getContextElementsSize() > index) {
					if (this.contextElementAt(index) != resourceElement) {
						this.addContextElement(index, resourceElement);
					}
				}
				else {
					this.addContextElement(index, resourceElement);			
				}
				index++;
			}
			
			for ( ; index < this.getContextElementsSize(); ) {
				this.removeContextElement(index);
			}
		}
	}

	/**
	 * Adapter used to synchronize a context list container with its corresponding
	 * resource container.
	 * @param <C> the type of context elements
	 * @param <R> the type of resource elements
	 */
	protected abstract class ContextListContainer<C extends JaxbContextNode, R>
		extends ContextCollectionContainer<C, R> {

		protected ContextListContainer() {
			super();
		}

		@Override
		public ListIterable<C> getContextElements() {
			return new LiveCloneListIterable<C>(this.contextElements);
		}

		@Override
		protected abstract ListIterable<R> getResourceElements();

		/**
		 * Return the index of the specified context element.
		 */
		public int indexOfContextElement(C contextElement) {
			return this.contextElements.indexOf(contextElement);
		}

		public C contextElementAt(int index) {
			return this.contextElements.elementAt(index);
		}

		/**
		 * Add a context element for the specified resource element at the
		 * specified index.
		 */
		@Override
		protected C addContextElement_(int index, C contextElement) {
			AbstractJaxbNode.this.addItemToList(index, contextElement, this.contextElements, this.getContextElementsPropertyName());
			return contextElement;
		}

		/**
		 * Move the context element at the specified target index to the 
		 * specified source index.
		 */
		public void moveContextElement(int targetIndex, int sourceIndex) {
			this.moveContextElement(targetIndex, this.contextElements.get(sourceIndex));
		}

		/**
		 * Move the specified context element to the specified index.
		 */
		@Override
		public void moveContextElement(int index, C element) {
			AbstractJaxbNode.this.moveItemInList(index, element, this.contextElements, this.getContextElementsPropertyName());
		}

		/**
		 * Remove the context element at the specified index from the container.
		 */
		public void removeContextElement(int index) {
			AbstractJaxbNode.this.removeItemFromList(index, this.contextElements, this.getContextElementsPropertyName());
		}
	}
}
