/*******************************************************************************
 * Copyright (c) 2007, 2009 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.context.java;

import java.util.Iterator;
import java.util.ListIterator;
import java.util.Vector;

import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jpt.core.context.Table;
import org.eclipse.jpt.core.context.UniqueConstraint;
import org.eclipse.jpt.core.context.java.JavaJpaContextNode;
import org.eclipse.jpt.core.context.java.JavaUniqueConstraint;
import org.eclipse.jpt.core.resource.java.BaseTableAnnotation;
import org.eclipse.jpt.core.resource.java.UniqueConstraintAnnotation;
import org.eclipse.jpt.core.utility.TextRange;
import org.eclipse.jpt.db.Catalog;
import org.eclipse.jpt.db.Database;
import org.eclipse.jpt.db.Schema;
import org.eclipse.jpt.db.SchemaContainer;
import org.eclipse.jpt.utility.Filter;
import org.eclipse.jpt.utility.internal.CollectionTools;
import org.eclipse.jpt.utility.internal.NameTools;
import org.eclipse.jpt.utility.internal.StringTools;
import org.eclipse.jpt.utility.internal.iterators.CloneListIterator;
import org.eclipse.jpt.utility.internal.iterators.EmptyIterator;
import org.eclipse.jpt.utility.internal.iterators.FilteringIterator;

/**
 * Java table
 */
public abstract class AbstractJavaTable
	extends AbstractJavaJpaContextNode
	implements Table, UniqueConstraint.Owner
{
	protected String specifiedName;
	protected String defaultName;

	protected String specifiedSchema;
	protected String defaultSchema;

	protected String specifiedCatalog;
	protected String defaultCatalog;

	protected final Vector<JavaUniqueConstraint> uniqueConstraints = new Vector<JavaUniqueConstraint>();


	// ********** constructor **********

	protected AbstractJavaTable(JavaJpaContextNode parent) {
		super(parent);
	}


	// ********** abstract methods **********

	/**
	 * Return the Java table annotation. Do not return null if the Java
	 * annotation does not exist; return a null table annotation instead.
	 */
	protected abstract BaseTableAnnotation getAnnotation();

	/**
	 * Return the name of the Java annotation.
	 */
	protected abstract String getAnnotationName();

	protected abstract String buildDefaultName();

	protected abstract String buildDefaultSchema();

	protected abstract String buildDefaultCatalog();


	// ********** name **********

	public String getName() {
		return (this.specifiedName != null) ? this.specifiedName : this.defaultName;
	}

	public String getSpecifiedName() {
		return this.specifiedName;
	}

	public void setSpecifiedName(String name) {
		String old = this.specifiedName;
		this.specifiedName = name;
		this.getAnnotation().setName(name);
		this.firePropertyChanged(SPECIFIED_NAME_PROPERTY, old, name);
	}

	/**
	 * internal setter used only for updating from the resource model.
	 * There were problems with InvalidThreadAccess exceptions in the UI
	 * when you set a value from the UI and the annotation doesn't exist yet.
	 * Adding the annotation causes an update to occur and then the exception.
	 */
	protected void setSpecifiedName_(String name) {
		String old = this.specifiedName;
		this.specifiedName = name;
		this.firePropertyChanged(SPECIFIED_NAME_PROPERTY, old, name);
	}

	public String getDefaultName() {
		return this.defaultName;
	}

	protected void setDefaultName(String name) {
		String old = this.defaultName;
		this.defaultName = name;
		this.firePropertyChanged(DEFAULT_NAME_PROPERTY, old, name);
	}


	// ********** schema **********

	public String getSchema() {
		return (this.specifiedSchema != null) ? this.specifiedSchema : this.defaultSchema;
	}

	public String getSpecifiedSchema() {
		return this.specifiedSchema;
	}

	public void setSpecifiedSchema(String schema) {
		String old = this.specifiedSchema;
		this.specifiedSchema = schema;
		this.getAnnotation().setSchema(schema);
		this.firePropertyChanged(SPECIFIED_SCHEMA_PROPERTY, old, schema);
	}

	/**
	 * internal setter used only for updating from the resource model.
	 * There were problems with InvalidThreadAccess exceptions in the UI
	 * when you set a value from the UI and the annotation doesn't exist yet.
	 * Adding the annotation causes an update to occur and then the exception.
	 */
	protected void setSpecifiedSchema_(String newSpecifiedSchema) {
		String oldSpecifiedSchema = this.specifiedSchema;
		this.specifiedSchema = newSpecifiedSchema;
		firePropertyChanged(SPECIFIED_SCHEMA_PROPERTY, oldSpecifiedSchema, newSpecifiedSchema);
	}

	public String getDefaultSchema() {
		return this.defaultSchema;
	}

	protected void setDefaultSchema(String schema) {
		String old = this.defaultSchema;
		this.defaultSchema = schema;
		this.firePropertyChanged(DEFAULT_SCHEMA_PROPERTY, old, schema);
	}


	// ********** catalog **********

	public String getCatalog() {
		return (this.specifiedCatalog != null) ? this.specifiedCatalog : this.defaultCatalog;
	}

	public String getSpecifiedCatalog() {
		return this.specifiedCatalog;
	}

	public void setSpecifiedCatalog(String catalog) {
		String old = this.specifiedCatalog;
		this.specifiedCatalog = catalog;
		this.getAnnotation().setCatalog(catalog);
		this.firePropertyChanged(SPECIFIED_CATALOG_PROPERTY, old, catalog);
	}

	/**
	 * internal setter used only for updating from the resource model.
	 * There were problems with InvalidThreadAccess exceptions in the UI
	 * when you set a value from the UI and the annotation doesn't exist yet.
	 * Adding the annotation causes an update to occur and then the exception.
	 */
	protected void setSpecifiedCatalog_(String catalog) {
		String old = this.specifiedCatalog;
		this.specifiedCatalog = catalog;
		this.firePropertyChanged(SPECIFIED_CATALOG_PROPERTY, old, catalog);
	}

	public String getDefaultCatalog() {
		return this.defaultCatalog;
	}

	protected void setDefaultCatalog(String catalog) {
		String old = this.defaultCatalog;
		this.defaultCatalog = catalog;
		this.firePropertyChanged(DEFAULT_CATALOG_PROPERTY, old, catalog);
	}


	// ********** unique constraints **********

	public @SuppressWarnings("unchecked") ListIterator<JavaUniqueConstraint> uniqueConstraints() {
		return new CloneListIterator<JavaUniqueConstraint>(this.uniqueConstraints);
	}

	public int uniqueConstraintsSize() {
		return this.uniqueConstraints.size();
	}

	public JavaUniqueConstraint addUniqueConstraint(int index) {
		JavaUniqueConstraint uniqueConstraint = getJpaFactory().buildJavaUniqueConstraint(this, this);
		this.uniqueConstraints.add(index, uniqueConstraint);
		UniqueConstraintAnnotation uniqueConstraintAnnotation = this.getAnnotation().addUniqueConstraint(index);
		uniqueConstraint.initialize(uniqueConstraintAnnotation);
		fireItemAdded(UNIQUE_CONSTRAINTS_LIST, index, uniqueConstraint);
		return uniqueConstraint;
	}

	public void removeUniqueConstraint(UniqueConstraint uniqueConstraint) {
		this.removeUniqueConstraint(this.uniqueConstraints.indexOf(uniqueConstraint));
	}

	public void removeUniqueConstraint(int index) {
		JavaUniqueConstraint removedUniqueConstraint = this.uniqueConstraints.remove(index);
		this.getAnnotation().removeUniqueConstraint(index);
		fireItemRemoved(UNIQUE_CONSTRAINTS_LIST, index, removedUniqueConstraint);
	}

	public void moveUniqueConstraint(int targetIndex, int sourceIndex) {
		CollectionTools.move(this.uniqueConstraints, targetIndex, sourceIndex);
		this.getAnnotation().moveUniqueConstraint(targetIndex, sourceIndex);
		fireItemMoved(UNIQUE_CONSTRAINTS_LIST, targetIndex, sourceIndex);
	}

	protected void addUniqueConstraint(int index, JavaUniqueConstraint uniqueConstraint) {
		addItemToList(index, uniqueConstraint, this.uniqueConstraints, UNIQUE_CONSTRAINTS_LIST);
	}

	protected void addUniqueConstraint(JavaUniqueConstraint uniqueConstraint) {
		this.addUniqueConstraint(this.uniqueConstraints.size(), uniqueConstraint);
	}

	protected void removeUniqueConstraint_(JavaUniqueConstraint uniqueConstraint) {
		removeItemFromList(uniqueConstraint, this.uniqueConstraints, UNIQUE_CONSTRAINTS_LIST);
	}

	protected void initializeUniqueConstraints(BaseTableAnnotation baseTableAnnotation) {
		for (Iterator<UniqueConstraintAnnotation> stream = baseTableAnnotation.uniqueConstraints(); stream.hasNext(); ) {
			this.uniqueConstraints.add(buildUniqueConstraint(stream.next()));
		}
	}

	protected void updateUniqueConstraints(BaseTableAnnotation baseTableAnnotation) {
		ListIterator<UniqueConstraintAnnotation> constraintAnnotations = baseTableAnnotation.uniqueConstraints();
		ListIterator<JavaUniqueConstraint> constraints = this.uniqueConstraints();
		while (constraints.hasNext()) {
			JavaUniqueConstraint uniqueConstraint = constraints.next();
			if (constraintAnnotations.hasNext()) {
				uniqueConstraint.update(constraintAnnotations.next());
			} else {
				this.removeUniqueConstraint_(uniqueConstraint);
			}
		}

		while (constraintAnnotations.hasNext()) {
			this.addUniqueConstraint(this.buildUniqueConstraint(constraintAnnotations.next()));
		}
	}

	protected JavaUniqueConstraint buildUniqueConstraint(UniqueConstraintAnnotation uniqueConstraintAnnotation) {
		JavaUniqueConstraint uniqueConstraint = this.getJpaFactory().buildJavaUniqueConstraint(this, this);
		uniqueConstraint.initialize(uniqueConstraintAnnotation);
		return uniqueConstraint;
	}


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

	protected TextRange getTextRange(TextRange textRange, CompilationUnit astRoot) {
		return (textRange != null) ? textRange : this.getParent().getValidationTextRange(astRoot);
	}

	protected TextRange getNameTextRange(CompilationUnit astRoot) {
		return this.getTextRange(this.getAnnotation().getNameTextRange(astRoot), astRoot);
	}

	protected boolean nameTouches(int pos, CompilationUnit astRoot) {
		return this.getAnnotation().nameTouches(pos, astRoot);
	}

	protected TextRange getSchemaTextRange(CompilationUnit astRoot) {
		return this.getTextRange(this.getAnnotation().getSchemaTextRange(astRoot), astRoot);
	}

	protected boolean schemaTouches(int pos, CompilationUnit astRoot) {
		return this.getAnnotation().schemaTouches(pos, astRoot);
	}

	protected TextRange getCatalogTextRange(CompilationUnit astRoot) {
		return this.getTextRange(this.getAnnotation().getCatalogTextRange(astRoot), astRoot);
	}

	protected boolean catalogTouches(int pos, CompilationUnit astRoot) {
		return this.getAnnotation().catalogTouches(pos, astRoot);
	}


	// ********** resource => context **********

	protected void initialize(BaseTableAnnotation baseTableAnnotation) {
		this.defaultName = this.buildDefaultName();
		this.specifiedName = baseTableAnnotation.getName();

		this.defaultSchema = this.buildDefaultSchema();
		this.specifiedSchema = baseTableAnnotation.getSchema();

		this.defaultCatalog = this.buildDefaultCatalog();
		this.specifiedCatalog = baseTableAnnotation.getCatalog();

		this.initializeUniqueConstraints(baseTableAnnotation);
	}

	protected void update(BaseTableAnnotation baseTableAnnotation) {
		this.setDefaultName(this.buildDefaultName());
		this.setSpecifiedName_(baseTableAnnotation.getName());

		this.setDefaultSchema(this.buildDefaultSchema());
		this.setSpecifiedSchema_(baseTableAnnotation.getSchema());

		this.setDefaultCatalog(this.buildDefaultCatalog());
		this.setSpecifiedCatalog_(baseTableAnnotation.getCatalog());

		this.updateUniqueConstraints(baseTableAnnotation);
	}


	// ********** database **********

	public org.eclipse.jpt.db.Table getDbTable() {
		Schema dbSchema = this.getDbSchema();
		return (dbSchema == null) ? null : dbSchema.getTableForIdentifier(this.getName());
	}

	public Schema getDbSchema() {
		SchemaContainer dbSchemaContainer = this.getDbSchemaContainer();
		return (dbSchemaContainer == null) ? null : dbSchemaContainer.getSchemaForIdentifier(this.getSchema());
	}

	/**
	 * If we don't have a catalog (i.e. we don't even have a <em>default</em> catalog),
	 * then the database probably does not support catalogs; and we need to
	 * get the schema directly from the database.
	 */
	public SchemaContainer getDbSchemaContainer() {
		String catalog = this.getCatalog();
		return (catalog != null) ? this.getDbCatalog(catalog) : this.getDatabase();
	}

	/**
	 * If we don't have a catalog (i.e. we don't even have a <em>default</em>
	 * catalog), then the database probably does not support catalogs.
	 */
	public Catalog getDbCatalog() {
		String catalog = this.getCatalog();
		return (catalog == null) ? null : this.getDbCatalog(catalog);
	}

	public boolean isResolved() {
		return this.getDbTable() != null;
	}

	public boolean hasResolvedSchema() {
		return this.getDbSchema() != null;
	}

	/**
	 * If we don't have a catalog (i.e. we don't even have a <em>default</em>
	 * catalog), then the database probably does not support catalogs.
	 */
	public boolean hasResolvedCatalog() {
		String catalog = this.getCatalog();
		return (catalog == null) || (this.getDbCatalog(catalog) != null);
	}


	// ********** UniqueConstraint.Owner implementation **********

	public Iterator<String> candidateUniqueConstraintColumnNames() {
		org.eclipse.jpt.db.Table dbTable = this.getDbTable();
		return (dbTable != null) ? dbTable.sortedColumnIdentifiers() : EmptyIterator.<String>instance();
	}


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

	public TextRange getValidationTextRange(CompilationUnit astRoot) {
		return this.getTextRange(this.getAnnotation().getTextRange(astRoot), astRoot);
	}


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

	@Override
	public Iterator<String> javaCompletionProposals(int pos, Filter<String> filter, CompilationUnit astRoot) {
		Iterator<String> result = super.javaCompletionProposals(pos, filter, astRoot);
		if (result != null) {
			return result;
		}
		for (JavaUniqueConstraint constraint : CollectionTools.iterable(this.uniqueConstraints())) {
			result = constraint.javaCompletionProposals(pos, filter, astRoot);
			if (result != null) {
				return result;
			}
		}
		return null;
	}

	/**
	 * called if the database is connected:
	 * name, schema, catalog
	 */
	@Override
	public Iterator<String> connectedJavaCompletionProposals(int pos, Filter<String> filter, CompilationUnit astRoot) {
		Iterator<String> result = super.connectedJavaCompletionProposals(pos, filter, astRoot);
		if (result != null) {
			return result;
		}
		if (this.nameTouches(pos, astRoot)) {
			return this.javaCandidateNames(filter);
		}
		if (this.schemaTouches(pos, astRoot)) {
			return this.javaCandidateSchemata(filter);
		}
		if (this.catalogTouches(pos, astRoot)) {
			return this.javaCandidateCatalogs(filter);
		}
		return null;
	}

	protected Iterator<String> javaCandidateNames(Filter<String> filter) {
		return StringTools.convertToJavaStringLiterals(this.candidateNames(filter));
	}

	protected Iterator<String> candidateNames(Filter<String> filter) {
		return new FilteringIterator<String, String>(this.candidateNames(), filter);
	}

	protected Iterator<String> candidateNames() {
		Schema dbSchema = this.getDbSchema();
		return (dbSchema != null) ? dbSchema.sortedTableIdentifiers() : EmptyIterator.<String> instance();
	}

	protected Iterator<String> javaCandidateSchemata(Filter<String> filter) {
		return StringTools.convertToJavaStringLiterals(this.candidateSchemata(filter));
	}

	protected Iterator<String> candidateSchemata(Filter<String> filter) {
		return new FilteringIterator<String, String>(this.candidateSchemata(), filter);
	}

	protected Iterator<String> candidateSchemata() {
		return this.getDbSchemaContainer().sortedSchemaIdentifiers();
	}

	protected Iterator<String> javaCandidateCatalogs(Filter<String> filter) {
		return StringTools.convertToJavaStringLiterals(this.candidateCatalogs(filter));
	}

	protected Iterator<String> candidateCatalogs(Filter<String> filter) {
		return new FilteringIterator<String, String>(this.candidateCatalogs(), filter);
	}

	protected Iterator<String> candidateCatalogs() {
		Database db = this.getDatabase();
		return (db != null) ? db.sortedCatalogIdentifiers() : EmptyIterator.<String> instance();
	}


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

	/**
	 * covariant override
	 */
	@Override
	public JavaJpaContextNode getParent() {
		return (JavaJpaContextNode) super.getParent();
	}

	@Override
	public void toString(StringBuilder sb) {
		super.toString(sb);
		sb.append(this.getQualifiedName());
	}

	protected String getQualifiedName() {
		return NameTools.buildQualifiedDatabaseObjectName(this.getCatalog(), this.getSchema(), this.getName());
	}

}
