/*******************************************************************************
 * Copyright (c) 2007, 2016 Oracle. 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/.
 *
 * Contributors:
 *     Oracle - initial API and implementation
 ******************************************************************************/
package org.eclipse.jpt.jpa.core.internal.jpa1.context.orm;

import java.util.List;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jpt.common.core.utility.TextRange;
import org.eclipse.jpt.jpa.core.context.NamedColumn;
import org.eclipse.jpt.jpa.core.context.OrderBy;
import org.eclipse.jpt.jpa.core.context.orm.OrmAttributeMapping;
import org.eclipse.jpt.jpa.core.context.orm.OrmSpecifiedPersistentAttribute;
import org.eclipse.jpt.jpa.core.internal.context.JpaValidator;
import org.eclipse.jpt.jpa.core.internal.context.orm.AbstractOrmXmlContextModel;
import org.eclipse.jpt.jpa.core.internal.jpa2.context.OrderColumnValidator;
import org.eclipse.jpt.jpa.core.jpa2.context.SpecifiedOrderColumn2_0;
import org.eclipse.jpt.jpa.core.jpa2.context.orm.OrmOrderable2_0;
import org.eclipse.jpt.jpa.core.jpa2.context.orm.OrmSpecifiedOrderColumn2_0;
import org.eclipse.jpt.jpa.core.resource.orm.OrmFactory;
import org.eclipse.jpt.jpa.core.resource.orm.XmlOrderBy;
import org.eclipse.jpt.jpa.core.resource.orm.XmlOrderColumn;
import org.eclipse.jpt.jpa.core.resource.orm.XmlOrderable;
import org.eclipse.jpt.jpa.db.Table;
import org.eclipse.wst.validation.internal.provisional.core.IMessage;
import org.eclipse.wst.validation.internal.provisional.core.IReporter;

/**
 * <code>orm.xml</code> ordering
 * <p>
 *<strong>(JPA 2.0 only) NB:</strong> If both the "order-by" and the
 * "order-column" elements are present (which is prohibited by the JPA spec),
 * order by is ignored (although the model is still there).
 */
public class GenericOrmOrderable
		extends AbstractOrmXmlContextModel<OrmAttributeMapping>
		implements OrmOrderable2_0 {
	
	protected final OrmOrderable2_0.ParentAdapter parentAdapter;
	
	protected boolean noOrdering = false;
	
	protected boolean orderByOrdering = false;
	// never null
	protected OrderBy orderBy;
	
	protected boolean orderColumnOrdering = false;
	// this is null for JPA 1.0 mappings
	protected OrmSpecifiedOrderColumn2_0 orderColumn;  
	

	/**
	 * JPA 1.0
	 */
	public GenericOrmOrderable(OrmAttributeMapping parent) {
		this(new OrmOrderable2_0.ParentAdapter.Null(parent));
	}
	
	/**
	 * JPA 2.0
	 */
	public GenericOrmOrderable(OrmOrderable2_0.ParentAdapter parentAdapter) {
		super(parentAdapter.getOrderableParent());
		
		this.parentAdapter = parentAdapter;
		
		initNoOrdering();
		initOrderBy();
		initOrderColumn();
	}
	
	
	// ********** synchronize/update **********
	
	@Override
	public void synchronizeWithResourceModel(IProgressMonitor monitor) {
		super.synchronizeWithResourceModel(monitor);
		
		synchNoOrdering();
		syncOrderBy(monitor);
		syncOrderColumn(monitor);
	}
	
	@Override
	public void update(IProgressMonitor monitor) {
		super.update(monitor);
		this.updateOrderBy(monitor);
		this.updateOrderColumn(monitor);
	}
	
	
	// ***** no ordering *****
	
	public boolean isNoOrdering() {
		return this.noOrdering;
	}
	
	public void setNoOrdering() {
		setNoOrdering_(true);
		setOrderByOrdering_(false);
		setOrderColumnOrdering_(false);
		
		removeXmlOrderBy();
		removeXmlOrderColumn();
	}
	
	protected void setNoOrdering_(boolean noOrdering) {
		boolean old = this.noOrdering;
		this.noOrdering = noOrdering;
		this.firePropertyChanged(NO_ORDERING_PROPERTY, old, noOrdering);
	}
	
	protected void initNoOrdering() {
		this.noOrdering = buildNoOrdering();
	}
	
	protected void synchNoOrdering() {
		setNoOrdering_(buildNoOrdering());
	}
	
	protected boolean buildNoOrdering() {
		return isJpa2_0Compatible() ? buildNoOrdering2_0() : buildNoOrdering1_0();
	}
	
	/**
	 * both elements are missing
	 */
	protected boolean buildNoOrdering2_0() {
		return getXmlOrderBy() == null && getXmlOrderColumn() == null;
	}
	
	/**
	 * the order-by element is missing
	 */
	protected boolean buildNoOrdering1_0() {
		return this.getXmlOrderBy() == null;
	}
	
	
	// ***** order-by ordering *****
	
	public boolean isOrderByOrdering() {
		return this.orderByOrdering;
	}
	
	public void setOrderByOrdering() {
		setNoOrdering_(false);
		setOrderByOrdering_(true);
		setOrderColumnOrdering_(false);
		
		addXmlOrderBy();
		removeXmlOrderColumn();
	}

	protected void setOrderByOrdering_(boolean newOrderByOrdering) {
		boolean old = this.orderByOrdering;
		this.orderByOrdering = newOrderByOrdering;
		this.firePropertyChanged(ORDER_BY_ORDERING_PROPERTY, old, newOrderByOrdering);
	}
	
	public OrderBy getOrderBy() {
		return this.orderBy;
	}
	
	protected void initOrderBy() {
		this.orderByOrdering = buildOrderByOrdering();
		this.orderBy = buildOrderBy();
	}
	
	protected void syncOrderBy(IProgressMonitor monitor) {
		setOrderByOrdering_(buildOrderByOrdering());
		this.orderBy.synchronizeWithResourceModel(monitor);
	}
	
	protected void updateOrderBy(IProgressMonitor monitor) {
		this.orderBy.update(monitor);
	}
	
	protected boolean buildOrderByOrdering() {
		return isJpa2_0Compatible() ? buildOrderByOrdering2_0() : buildOrderByOrdering1_0();
	}
	
	/**
	 * order-by is present but order-column is not
	 */
	protected boolean buildOrderByOrdering2_0() {
		return getXmlOrderBy() != null && getXmlOrderColumn() == null;
	}
	
	/**
	 * order-by is present
	 */
	protected boolean buildOrderByOrdering1_0() {
		return getXmlOrderBy() != null;
	}
	
	protected OrderBy buildOrderBy() {
		return new GenericOrmOrderBy(this, new OrderByContext());
	}
	
	
	protected class OrderByContext
			implements GenericOrmOrderBy.Context {
		
		public XmlOrderBy getXmlOrderBy(boolean addIfAbsent) {
			XmlOrderBy xmlOrderBy = GenericOrmOrderable.this.getXmlOrderBy();
			if (xmlOrderBy == null && addIfAbsent) {
				xmlOrderBy = addXmlOrderBy();
			}
			return xmlOrderBy;
		}
	}
	
	
	// ***** order-column ordering *****
	
	public boolean isOrderColumnOrdering() {
		return this.orderColumnOrdering;
	}
	
	public void setOrderColumnOrdering() {
		setNoOrdering_(false);
		setOrderByOrdering_(false);
		setOrderColumnOrdering_(true);
		
		removeXmlOrderBy();
		addXmlOrderColumn();
	}
	
	protected void setOrderColumnOrdering_(boolean orderColumnOrdering) {
		boolean old = this.orderColumnOrdering;
		this.orderColumnOrdering = orderColumnOrdering;
		this.firePropertyChanged(ORDER_COLUMN_ORDERING_PROPERTY, old, orderColumnOrdering);
	}
	
	public OrmSpecifiedOrderColumn2_0 getOrderColumn() {
		return this.orderColumn;
	}
	
	protected void initOrderColumn() {
		this.orderColumnOrdering = buildOrderColumnOrdering();
		this.orderColumn = buildOrderColumn();
	}
	
	protected void syncOrderColumn(IProgressMonitor monitor) {
		setOrderColumnOrdering_(buildOrderColumnOrdering());
		if (this.orderColumn != null) {
			this.orderColumn.synchronizeWithResourceModel(monitor);
		}
	}
	
	protected void updateOrderColumn(IProgressMonitor monitor) {
		if (this.orderColumn != null) {
			this.orderColumn.update(monitor);
		}
	}
	
	/**
	 * Only true if JPA 2.0 *and* order-column is present
	 */
	protected boolean buildOrderColumnOrdering() {
		return isJpa2_0Compatible() ? getXmlOrderColumn() != null : false;
	}
	
	/**
	 * non-null for JPA 2.0(+) only
	 */
	protected OrmSpecifiedOrderColumn2_0 buildOrderColumn() {
		return this.isOrmXml2_0Compatible() ?
				this.getContextModelFactory2_0().buildOrmOrderColumn(new OrderColumnParentAdapter()) :
				null;
	}
	
	
	// ********** xml order by **********

	protected XmlOrderBy getXmlOrderBy() {
		return this.getXmlOrderable().getOrderBy();
	}
	
	protected XmlOrderBy addXmlOrderBy() {
		XmlOrderBy xmlOrderBy = OrmFactory.eINSTANCE.createXmlOrderBy();
		getXmlOrderable().setOrderBy(xmlOrderBy);
		return xmlOrderBy;
	}
	
	protected void removeXmlOrderBy() {
		getXmlOrderable().setOrderBy(null);
	}
	
	
	// ********** xml order column **********

	protected XmlOrderColumn getXmlOrderColumn() {
		return this.getXmlOrderable().getOrderColumn();
	}
	
	protected XmlOrderColumn addXmlOrderColumn() {
		XmlOrderColumn xmlColumn = OrmFactory.eINSTANCE.createXmlOrderColumn();
		GenericOrmOrderable.this.getXmlOrderable().setOrderColumn(xmlColumn);
		return xmlColumn;
	}
	
	protected void removeXmlOrderColumn() {
		getXmlOrderable().setOrderColumn(null);
	}
	
	
	// ********** misc **********

	protected OrmAttributeMapping getAttributeMapping() {
		return this.parent;
	}

	protected OrmSpecifiedPersistentAttribute getPersistentAttribute() {
		return this.getAttributeMapping().getPersistentAttribute();
	}

	protected XmlOrderable getXmlOrderable() {
		return (XmlOrderable) this.getAttributeMapping().getXmlAttributeMapping();
	}

	// JPA 2.0
	public String getDefaultTableName() {
		return this.parentAdapter.getTableName();
	}

	// JPA 2.0
	protected Table resolveDbTable(String tableName) {
		return this.parentAdapter.resolveDbTable(tableName);
	}


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

	public TextRange getValidationTextRange() {
		TextRange textRange = this.getXmlOrderable().getValidationTextRange();
		return (textRange != null) ? textRange : this.getAttributeMapping().getValidationTextRange();
	}

	@Override
	public void validate(List<IMessage> messages, IReporter reporter) {
		super.validate(messages, reporter);
		// order-column and order-by both specified is handled with schema validation
		if (this.orderColumnOrdering) {
			// TODO validation message if type is not List
			this.orderColumn.validate(messages, reporter);
		}
	}

	// ********** completion proposals **********

	@Override
	public Iterable<String> getCompletionProposals(int pos) {
		Iterable<String> result = super.getCompletionProposals(pos);
		if (result != null) {
			return result;
		}
		// orderColumn is null for JPA 1.0 mappings so adding a null
		// check here to prevent NPE - Bug 375670
		if (this.orderColumn != null) {
			result = this.orderColumn.getCompletionProposals(pos);
			if (result != null) {
				return result;
			}
		}
		return null;
	}
	
	// ********** order column parent adapter (JPA 2.0) **********

	public class OrderColumnParentAdapter
		implements OrmSpecifiedOrderColumn2_0.ParentAdapter
	{
		public OrmOrderable2_0 getColumnParent() {
			return GenericOrmOrderable.this;
		}

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

		public Table resolveDbTable(String tableName) {
			return GenericOrmOrderable.this.resolveDbTable(tableName);
		}

		public String getDefaultColumnName(NamedColumn column) {
			return this.getPersistentAttribute().getName() + "_ORDER"; //$NON-NLS-1$
		}

		public TextRange getValidationTextRange() {
			return GenericOrmOrderable.this.getValidationTextRange();
		}

		public JpaValidator buildColumnValidator(NamedColumn column) {
			return new OrderColumnValidator(this.getPersistentAttribute(), (SpecifiedOrderColumn2_0) column);
		}

		public XmlOrderColumn getXmlColumn() {
			return GenericOrmOrderable.this.getXmlOrderColumn();
		}

		public XmlOrderColumn buildXmlColumn() {
			return GenericOrmOrderable.this.addXmlOrderColumn();
		}

		public void removeXmlColumn() {
			GenericOrmOrderable.this.removeXmlOrderColumn();
		}

		protected OrmSpecifiedPersistentAttribute getPersistentAttribute() {
			return GenericOrmOrderable.this.getPersistentAttribute();
		}
	}
}
