/*******************************************************************************
 * Copyright (c) 2010 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.core.internal.jpa1.context.orm;

import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Vector;
import org.eclipse.jpt.common.core.utility.TextRange;
import org.eclipse.jpt.common.utility.internal.CollectionTools;
import org.eclipse.jpt.common.utility.internal.iterables.CompositeListIterable;
import org.eclipse.jpt.common.utility.internal.iterables.EmptyIterable;
import org.eclipse.jpt.common.utility.internal.iterables.ListIterable;
import org.eclipse.jpt.common.utility.internal.iterables.LiveCloneListIterable;
import org.eclipse.jpt.common.utility.internal.iterators.EmptyIterator;
import org.eclipse.jpt.common.utility.internal.iterators.FilteringIterator;
import org.eclipse.jpt.core.context.BaseColumn;
import org.eclipse.jpt.core.context.Override_;
import org.eclipse.jpt.core.context.TypeMapping;
import org.eclipse.jpt.core.context.VirtualOverride;
import org.eclipse.jpt.core.context.XmlContextNode;
import org.eclipse.jpt.core.context.orm.OrmOverride;
import org.eclipse.jpt.core.context.orm.OrmOverrideContainer;
import org.eclipse.jpt.core.context.orm.OrmReadOnlyOverride;
import org.eclipse.jpt.core.context.orm.OrmVirtualOverride;
import org.eclipse.jpt.core.internal.context.BaseColumnTextRangeResolver;
import org.eclipse.jpt.core.internal.context.ContextContainerTools;
import org.eclipse.jpt.core.internal.context.JptValidator;
import org.eclipse.jpt.core.internal.context.OverrideTextRangeResolver;
import org.eclipse.jpt.core.internal.context.orm.AbstractOrmXmlContextNode;
import org.eclipse.jpt.core.resource.orm.XmlOverride;
import org.eclipse.wst.validation.internal.provisional.core.IMessage;
import org.eclipse.wst.validation.internal.provisional.core.IReporter;

/**
 * <code>orm.xml</code> override container
 */
public abstract class AbstractOrmOverrideContainer<
			O extends OrmOverrideContainer.Owner,
			R extends OrmReadOnlyOverride,
			S extends OrmOverride,
			V extends OrmVirtualOverride,
			X extends XmlOverride
		>
	extends AbstractOrmXmlContextNode
	implements OrmOverrideContainer
{
	// this can be null if the container is "read-only" (i.e. a "null" container)
	protected final O owner;

	protected final Vector<S> specifiedOverrides = new Vector<S>();
	protected final SpecifiedOverrideContainerAdapter specifiedOverrideContainerAdapter = new SpecifiedOverrideContainerAdapter();

	protected final Vector<V> virtualOverrides = new Vector<V>();
	protected final VirtualOverrideContainerAdapter virtualOverrideContainerAdapter = new VirtualOverrideContainerAdapter();


	protected AbstractOrmOverrideContainer(XmlContextNode parent, O owner) {
		super(parent);
		this.owner = owner;
		this.initializeSpecifiedOverrides();
	}


	// ********** synchronize/update **********

	@Override
	public void synchronizeWithResourceModel() {
		super.synchronizeWithResourceModel();
		this.syncSpecifiedOverrides();
		// the virtual overrides do not need a sync
	}

	@Override
	public void update() {
		super.update();
		this.updateNodes(this.getSpecifiedOverrides());
		this.updateVirtualOverrides();
	}


	// ********** overrides **********

	public ListIterator<R> overrides() {
		return this.getOverrides().iterator();
	}

	@SuppressWarnings("unchecked")
	protected ListIterable<R> getOverrides() {
		return new CompositeListIterable<R>(this.getReadOnlySpecifiedOverrides(), this.getReadOnlyVirtualOverrides());
	}

	public int overridesSize() {
		return this.specifiedOverrides.size() + this.virtualOverrides.size();
	}

	public R getOverrideNamed(String name) {
		return this.selectOverrideNamed(this.getOverrides(), name);
	}


	// ********** override conversions **********

	/**
	 * <em>Silently</em> add the new virtual override before removing the
	 * specified override, or the <em>update</em> will discover the missing
	 * virtual override and add it preemptively.
	 */
	public V convertOverrideToVirtual(Override_ override) {
		if (override.isVirtual()) {
			throw new IllegalArgumentException("Override is already virtual: " + override); //$NON-NLS-1$
		}

		@SuppressWarnings("unchecked")
		S specifiedOverride = (S) override;
		int virtualIndex = this.virtualOverrides.size();
		String overrideName = specifiedOverride.getName();
		V virtualOverride = null;
		// make sure the specified override actually overrides something before building the virtual override
		if (this.overrideWillBeVirtual(overrideName, specifiedOverride)) {
			virtualOverride = this.buildVirtualOverride(overrideName);
			this.virtualOverrides.add(virtualIndex, virtualOverride);
		}

		this.removeSpecifiedOverride(specifiedOverride);  // trigger update

		if (virtualOverride != null) {
			this.fireItemAdded(VIRTUAL_OVERRIDES_LIST, virtualIndex, virtualOverride);
		}
		return virtualOverride;
	}

	/**
	 * Return whether the specified override name will be a
	 * <em>virtual</em> override when the specified specified override is
	 * removed from the container. The override name must be among the
	 * valid override names and it must not correspond to any of the
	 * remaining specified overrides.
	 */
	protected boolean overrideWillBeVirtual(String overrideName, S specifiedOverrideToBeRemoved) {
		return CollectionTools.contains(this.allOverridableNames(), overrideName) &&
				(this.getSpecifiedOverrideNamed(overrideName, specifiedOverrideToBeRemoved) == null);
	}

	/**
	 * <em>Silently</em> remove the virtual override and add the new specified
	 * override before naming the specified override, or the <em>update</em>
	 * will discover the dangling virtual override and remove it preemptively.
	 */
	public S convertOverrideToSpecified(VirtualOverride override) {
		if ( ! override.isVirtual()) {
			throw new IllegalArgumentException("Override is already specified: " + override); //$NON-NLS-1$
		}

		@SuppressWarnings("unchecked")
		V virtualOverride = (V) override;
		int virtualIndex = this.virtualOverrides.indexOf(virtualOverride);
		this.virtualOverrides.remove(virtualIndex);

		int specifiedIndex = this.specifiedOverrides.size();
		X xmlOverride = this.buildXmlOverride();
		S specifiedOverride = this.buildSpecifiedOverride(xmlOverride);
		this.specifiedOverrides.add(specifiedIndex, specifiedOverride);
		this.owner.getXmlOverrides().add(specifiedIndex, xmlOverride);

		this.initializeSpecifiedOverride(specifiedOverride, virtualOverride);  // trigger update

		this.fireItemRemoved(VIRTUAL_OVERRIDES_LIST, virtualIndex, virtualOverride);
		this.fireItemAdded(SPECIFIED_OVERRIDES_LIST, specifiedIndex, specifiedOverride);
		return specifiedOverride;
	}

	protected abstract void initializeSpecifiedOverride(S specifiedOverride, V virtualOverride);


	// ********** specified overrides **********

	public ListIterator<S> specifiedOverrides() {
		return this.getSpecifiedOverrides().iterator();
	}

	protected ListIterable<S> getSpecifiedOverrides() {
		return new LiveCloneListIterable<S>(this.specifiedOverrides);
	}

	@SuppressWarnings("unchecked")
	protected ListIterable<R> getReadOnlySpecifiedOverrides() {
		// S should always be a subtype of R, but we can't enforce that in the
		// class declaration...
		return (ListIterable<R>) this.getSpecifiedOverrides();
	}

	public int specifiedOverridesSize() {
		return this.specifiedOverrides.size();
	}

	public S getSpecifiedOverride(int index) {
		return this.specifiedOverrides.get(index);
	}

	public S getSpecifiedOverrideNamed(String name) {
		return this.getSpecifiedOverrideNamed(name, null);
	}

	@SuppressWarnings("unchecked")
	protected S getSpecifiedOverrideNamed(String name, S exclude) {
		return (S) this.selectOverrideNamed(this.getReadOnlySpecifiedOverrides(), name, exclude);
	}

	protected S addSpecifiedOverride() {
		return this.addSpecifiedOverride(this.specifiedOverrides.size());
	}

	protected S addSpecifiedOverride(int index) {
		X xmlOverride = this.buildXmlOverride();
		S override = this.addSpecifiedOverride_(index, xmlOverride);
		this.owner.getXmlOverrides().add(index, xmlOverride);
		return override;
	}

	protected abstract X buildXmlOverride();

	protected void removeSpecifiedOverride(S override) {
		this.removeSpecifiedOverride(this.specifiedOverrides.indexOf(override));
	}

	protected void removeSpecifiedOverride(int index) {
		this.removeSpecifiedOverride_(index);
		this.owner.getXmlOverrides().remove(index);
	}

	protected void removeSpecifiedOverride_(int index) {
		this.removeItemFromList(index, this.specifiedOverrides, SPECIFIED_OVERRIDES_LIST);
	}

	public void moveSpecifiedOverride(int targetIndex, int sourceIndex) {
		this.moveItemInList(targetIndex, sourceIndex, this.specifiedOverrides, SPECIFIED_OVERRIDES_LIST);
		this.owner.getXmlOverrides().move(targetIndex, sourceIndex);
	}

	protected void initializeSpecifiedOverrides() {
		for (X xmlOverride : this.getXmlOverrides()) {
			this.specifiedOverrides.add(this.buildSpecifiedOverride(xmlOverride));
		}
	}

	protected abstract S buildSpecifiedOverride(X xmlOverride);

	protected void syncSpecifiedOverrides() {
		ContextContainerTools.synchronizeWithResourceModel(this.specifiedOverrideContainerAdapter);
	}

	protected Iterable<X> getXmlOverrides() {
		return (this.owner == null) ? EmptyIterable.<X>instance() : this.getXmlOverrides_();
	}

	/**
	 * pre-condition: {@link #owner} is not <code>null</code>
	 */
	protected abstract Iterable<X> getXmlOverrides_();

	protected void moveSpecifiedOverride_(int index, S override) {
		this.moveItemInList(index, override, this.specifiedOverrides, SPECIFIED_OVERRIDES_LIST);
	}

	protected S addSpecifiedOverride_(int index, X xmlOverride) {
		S override = this.buildSpecifiedOverride(xmlOverride);
		this.addItemToList(index, override, this.specifiedOverrides, SPECIFIED_OVERRIDES_LIST);
		return override;
	}

	protected void removeSpecifiedOverride_(S override) {
		this.removeSpecifiedOverride_(this.specifiedOverrides.indexOf(override));
	}

	/**
	 * specified override container adapter
	 */
	protected class SpecifiedOverrideContainerAdapter
		implements ContextContainerTools.Adapter<S, X>
	{
		public Iterable<S> getContextElements() {
			return AbstractOrmOverrideContainer.this.getSpecifiedOverrides();
		}
		public Iterable<X> getResourceElements() {
			return AbstractOrmOverrideContainer.this.getXmlOverrides();
		}
		@SuppressWarnings("unchecked")
		public X getResourceElement(S contextElement) {
			return (X) contextElement.getXmlOverride();
		}
		public void moveContextElement(int index, S element) {
			AbstractOrmOverrideContainer.this.moveSpecifiedOverride_(index, element);
		}
		public void addContextElement(int index, X resourceElement) {
			AbstractOrmOverrideContainer.this.addSpecifiedOverride_(index, resourceElement);
		}
		public void removeContextElement(S element) {
			AbstractOrmOverrideContainer.this.removeSpecifiedOverride_(element);
		}
	}


	// ********** virtual overrides **********

	public ListIterator<V> virtualOverrides() {
		return this.getVirtualOverrides().iterator();
	}

	protected ListIterable<V> getVirtualOverrides() {
		return new LiveCloneListIterable<V>(this.virtualOverrides);
	}

	@SuppressWarnings("unchecked")
	protected ListIterable<R> getReadOnlyVirtualOverrides() {
		// V should always be a subtype of R, but we can't enforce that in the
		// class declaration...
		return (ListIterable<R>) this.getVirtualOverrides();
	}

	public int virtualOverridesSize() {
		return this.virtualOverrides.size();
	}

	protected void updateVirtualOverrides() {
		ContextContainerTools.update(this.virtualOverrideContainerAdapter);
	}

	/**
	 * Return the overridable names that are not already in the list of
	 * specified overrides.
	 */
	protected Iterable<String> getVirtualOverrideNames() {
		return CollectionTools.iterable(this.virtualOverrideNames());
	}

	protected Iterator<String> virtualOverrideNames() {
		return new FilteringIterator<String>(this.allOverridableNames()) {
			@Override
			protected boolean accept(String name) {
				return AbstractOrmOverrideContainer.this.overrideIsVirtual(name);
			}
		};
	}

	protected boolean overrideIsVirtual(String name) {
		return this.getSpecifiedOverrideNamed(name) == null;
	}

	protected void moveVirtualOverride(int index, V override) {
		this.moveItemInList(index, override, this.virtualOverrides, VIRTUAL_OVERRIDES_LIST);
	}

	protected V addVirtualOverride(int index, String name) {
		V override = this.buildVirtualOverride(name);
		this.addItemToList(index, override, this.virtualOverrides, VIRTUAL_OVERRIDES_LIST);
		return override;
	}

	protected abstract V buildVirtualOverride(String name);

	protected void removeVirtualOverride(V override) {
		this.removeItemFromList(override, this.virtualOverrides, VIRTUAL_OVERRIDES_LIST);
	}

	/**
	 * virtual override container adapter
	 * NB: the context override is matched with a resource override by name
	 */
	protected class VirtualOverrideContainerAdapter
		implements ContextContainerTools.Adapter<V, String>
	{
		public Iterable<V> getContextElements() {
			return AbstractOrmOverrideContainer.this.getVirtualOverrides();
		}
		public Iterable<String> getResourceElements() {
			return AbstractOrmOverrideContainer.this.getVirtualOverrideNames();
		}
		public String getResourceElement(V contextElement) {
			return contextElement.getName();
		}
		public void moveContextElement(int index, V element) {
			AbstractOrmOverrideContainer.this.moveVirtualOverride(index, element);
		}
		public void addContextElement(int index, String resourceElement) {
			AbstractOrmOverrideContainer.this.addVirtualOverride(index, resourceElement);
		}
		public void removeContextElement(V element) {
			AbstractOrmOverrideContainer.this.removeVirtualOverride(element);
		}
	}


	// ********** misc **********

	public TypeMapping getOverridableTypeMapping() {
		return this.owner.getOverridableTypeMapping();
	}

	public TypeMapping getTypeMapping() {
		return this.owner.getTypeMapping();
	}

	public Iterator<String> allOverridableNames() {
		return (this.owner != null) ? this.owner.allOverridableNames() : EmptyIterator.<String>instance();
	}

	public boolean tableNameIsInvalid(String tableName) {
		return this.owner.tableNameIsInvalid(tableName);
	}

	public Iterator<String> candidateTableNames() {
		return this.owner.candidateTableNames();
	}

	public org.eclipse.jpt.jpa.db.Table resolveDbTable(String tableName) {
		return this.owner.resolveDbTable(tableName);
	}

	public String getDefaultTableName() {
		return this.owner.getDefaultTableName();
	}

	public JptValidator buildValidator(Override_ override, OverrideTextRangeResolver textRangeResolver) {
		return this.owner.buildValidator(override, this, textRangeResolver);
	}

	public JptValidator buildColumnValidator(Override_ override, BaseColumn column, BaseColumn.Owner columnOwner, BaseColumnTextRangeResolver textRangeResolver) {
		return this.owner.buildColumnValidator(override, column, columnOwner, textRangeResolver);
	}

	protected R selectOverrideNamed(Iterable<R> overrides, String name) {
		return this.selectOverrideNamed(overrides, name, null);
	}

	protected R selectOverrideNamed(Iterable<R> overrides, String name, S exclude) {
		for (R override : overrides) {
			if (override == exclude) {
				continue;  // skip
			}
			if (this.valuesAreEqual(override.getName(), name)) {
				return override;
			}
		}
		return null;
	}


	// ********** validation **********

	@Override
	public void validate(List<IMessage> messages, IReporter reporter) {
		super.validate(messages, reporter);

		for (R override : this.getOverrides()) {
			override.validate(messages, reporter);
		}
	}

	public TextRange getValidationTextRange() {
		return (this.specifiedOverrides.size() > 0) ?
				this.specifiedOverrides.get(0).getValidationTextRange() :
				this.owner.getValidationTextRange();
	}
}
