/*******************************************************************************
 * Copyright (c) 2006, 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.gen.internal;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import org.eclipse.jpt.db.Column;
import org.eclipse.jpt.db.ForeignKey;
import org.eclipse.jpt.db.Table;
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.FilteringIterator;

/**
 * associate a table with the various relations that will be used when
 * generating the entity corresponding to the table
 */
class GenTable {
	private final GenScope scope;
	private final Table table;

	// these relations cannot be built until after we have built all the scope's tables
	private ManyToManyRelation joinTableRelation;
	private final ArrayList<ManyToManyRelation> ownedManyToManyRelations = new ArrayList<ManyToManyRelation>();
	private final ArrayList<ManyToManyRelation> nonOwnedManyToManyRelations = new ArrayList<ManyToManyRelation>();
	private final ArrayList<ManyToOneRelation> manyToOneRelations = new ArrayList<ManyToOneRelation>();
	private final ArrayList<OneToManyRelation> oneToManyRelations = new ArrayList<OneToManyRelation>();
	private final HashSet<Column> foreignKeyColumns = new HashSet<Column>();

	private final HashSet<String> attributeNames = new HashSet<String>();
	private String attributeNameForEmbeddedId;
	private final HashMap<Column, String> basicAttributeNames = new HashMap<Column, String>();
	private final HashMap<ManyToOneRelation, String> manyToOneAttributeNames = new HashMap<ManyToOneRelation, String>();
	private final HashMap<OneToManyRelation, String> oneToManyAttributeNames = new HashMap<OneToManyRelation, String>();
	private final HashMap<ManyToManyRelation, String> ownedManyToManyAttributeNames = new HashMap<ManyToManyRelation, String>();
	private final HashMap<ManyToManyRelation, String> nonOwnedManyToManyAttributeNames = new HashMap<ManyToManyRelation, String>();


	// ********** construction/initialization **********

	GenTable(GenScope scope, Table table) {
		super();
		this.scope = scope;
		this.table = table;
	}


	// ********** package API **********

	EntityGenerator.Config getEntityConfig() {
		return this.scope.getEntityConfig();
	}

	/**
	 * examples:
	 *   GenTable(FOO) => "FOO_COLLECTION"
	 *   GenTable(foo) => "fooCollection"
	 *   GenTable(Foo) => "FooCollection"
	 */
	String getCollectionAttributeName() {
		String name = this.getName();
		String suffix = this.getEntityConfig().getCollectionAttributeNameSuffix();
		if (StringTools.stringIsUppercase(name)) {  // hmmm  ~bjv
			suffix = '_' + suffix.toUpperCase();
		}
		return name + suffix;
	}

	/**
	 * determine whether the table is a "join" table within the table's scope;
	 * this can be removed, later, if we find another table references the,
	 * seemingly, join table
	 * @see #clearJoinTableRelation() (and callers)
	 */
	void buildJoinTableRelation() {
		if ( ! this.table.isPossibleJoinTable()) {
			return;  // the table must have exactly 2 foreign keys
		}
		ForeignKey owningFK = this.table.getJoinTableOwningForeignKey();
		GenTable owningGenTable = this.scope.getGenTable(owningFK.getReferencedTable());
		if (owningGenTable == null) {
			return;  // both tables must be in the scope
		}
		ForeignKey nonOwningFK = this.table.getJoinTableNonOwningForeignKey();
		GenTable nonOwningGenTable = this.scope.getGenTable(nonOwningFK.getReferencedTable());
		if (nonOwningGenTable == null) {
			return;  // both tables must be in the scope
		}
		this.joinTableRelation = new ManyToManyRelation(
											this,
											owningFK,
											owningGenTable,
											nonOwningFK,
											nonOwningGenTable
										);
	}

	/**
	 * used by the scope to figure out whether "join" tables should be
	 * converted to "entity" tables
	 */
	void addReferencedGenTablesTo(Set<GenTable> referencedTables) {
		for (Iterator<ForeignKey> stream = this.table.foreignKeys(); stream.hasNext(); ) {
			ForeignKey fk = stream.next();
			GenTable genTable = this.scope.getGenTable(fk.getReferencedTable());
			if (genTable != null) {
				referencedTables.add(genTable);
			}
		}
	}

	/**
	 * the scope clears the join table relation if there are any references
	 * to the join table from other tables in the scope
	 */
	void clearJoinTableRelation() {
		this.joinTableRelation.clear();
		this.joinTableRelation = null;
	}

	/**
	 * find "in-scope" foreign keys
	 */
	void buildManyToOneRelations() {
		for (Iterator<ForeignKey> stream = this.table.foreignKeys(); stream.hasNext(); ) {
			ForeignKey fk = stream.next();
			GenTable referencedGenTable = this.scope.getGenTable(fk.getReferencedTable());
			if (referencedGenTable != null) {
				this.manyToOneRelations.add(new ManyToOneRelation(this, fk, referencedGenTable));
			}
		}
	}

	/**
	 * now that all the relations are in place, we can configure the Java
	 * attribute names
	 */
	void buildAttributeNames() {
		this.buildAttributeNameForEmbeddedId();

		// gather up all the table's columns...
		Set<Column> columns = CollectionTools.set(this.table.columns(), this.table.columnsSize());
		// ...remove the columns that belong exclusively to many-to-one foreign keys...
		this.buildManyToOneAttributeNames(columns);
		// ...and use the remaining columns to generate "basic" attribute names
		this.buildBasicAttributeNames(columns);

		this.buildOneToManyAttributeNames();
		this.buildOwnedManyToManyAttributeNames();
		this.buildNonOwnedManyToManyAttributeNames();
	}

	/**
	 * return the columns that are part of the table's primary key
	 * but are also part of an "in-scope" foreign key
	 */
	Iterator<Column> readOnlyPrimaryKeyColumns() {
		return new FilteringIterator<Column, Column>(this.table.primaryKeyColumns()) {
			@Override
			protected boolean accept(Column pkColumn) {
				return pkColumn.isPartOfForeignKey();
			}
		};
	}

	/**
	 * return the columns that are part of the table's primary key
	 * but are NOT part of any "in-scope" foreign key
	 */
	Iterator<Column> writablePrimaryKeyColumns() {
		return new FilteringIterator<Column, Column>(this.table.primaryKeyColumns()) {
			@Override
			protected boolean accept(Column pkColumn) {
				return ! pkColumn.isPartOfForeignKey();
			}
		};
	}

	/**
	 * return the columns that NEITHER part of the table's primary key
	 * NOR part of any foreign key
	 */
	Iterator<Column> nonPrimaryKeyBasicColumns() {
		return new FilteringIterator<Column, Column>(this.table.columns()) {
			@Override
			protected boolean accept(Column column) {
				return ! (column.isPartOfPrimaryKey() || column.isPartOfForeignKey());
			}
		};
	}

	Table getTable() {
		return this.table;
	}

	String getEntityName() {
		return this.getEntityConfig().getEntityName(this.table);
	}

	boolean isJoinTable() {
		return this.joinTableRelation != null;
	}

	void addOwnedManyToManyRelation(ManyToManyRelation relation) {
		this.ownedManyToManyRelations.add(relation);
	}

	void removeOwnedManyToManyRelation(ManyToManyRelation relation) {
		this.ownedManyToManyRelations.remove(relation);
	}

	void addNonOwnedManyToManyRelation(ManyToManyRelation relation) {
		this.nonOwnedManyToManyRelations.add(relation);
	}

	void removeNonOwnedManyToManyRelation(ManyToManyRelation relation) {
		this.nonOwnedManyToManyRelations.remove(relation);
	}

	void addOneToManyRelation(OneToManyRelation relation) {
		this.oneToManyRelations.add(relation);
	}

	Iterator<ManyToOneRelation> manyToOneRelations() {
		return this.manyToOneRelations.iterator();
	}

	Iterator<OneToManyRelation> oneToManyRelations() {
		return this.oneToManyRelations.iterator();
	}

	Iterator<ManyToManyRelation> ownedManyToManyRelations() {
		return this.ownedManyToManyRelations.iterator();
	}

	Iterator<ManyToManyRelation> nonOwnedManyToManyRelations() {
		return this.nonOwnedManyToManyRelations.iterator();
	}

	/**
	 * this will return null if we don't want an embedded id attribute
	 */
	String getAttributeNameForEmbeddedId() {
		return this.attributeNameForEmbeddedId;
	}

	String getAttributeNameFor(Column column) {
		return this.basicAttributeNames.get(column);
	}

	String getAttributeNameFor(ManyToOneRelation relation) {
		return this.manyToOneAttributeNames.get(relation);
	}

	String getAttributeNameFor(OneToManyRelation relation) {
		return this.oneToManyAttributeNames.get(relation);
	}

	String getAttributeNameForOwned(ManyToManyRelation relation) {
		return this.ownedManyToManyAttributeNames.get(relation);
	}

	String getAttributeNameForNonOwned(ManyToManyRelation relation) {
		return this.nonOwnedManyToManyAttributeNames.get(relation);
	}

	String getName() {
		return this.table.getName();
	}

	boolean joinTableNameIsDefault() {
		return this.table.joinTableNameIsDefault();
	}


	// ********** internal API **********

	/**
	 * if we are going to generate an EmbeddedId attribute, add its name to
	 * 'attributeNames' so we don't collide with it later, when generating
	 * attribute names for the columns etc.
	 */
	private void buildAttributeNameForEmbeddedId() {
		if ((this.table.primaryKeyColumnsSize() > 1) && this.getEntityConfig().generateEmbeddedIdForCompoundPK()) {
			this.attributeNameForEmbeddedId = this.configureAttributeName(this.getEntityConfig().getEmbeddedIdAttributeName());
		}
	}

	/**
	 * While we are figuring out the names for the m:1 attributes, remove from the
	 * specified set of columns the columns that are only part of the foreign keys
	 * (leaving the remaining columns for basic attributes).
	 * Store the calculated names so we can get them back later, when we
	 * are generating source.
	 */
	private void buildManyToOneAttributeNames(Set<Column> columns) {
		for (ManyToOneRelation relation : this.manyToOneRelations) {
			CollectionTools.removeAll(columns, relation.getForeignKey().nonPrimaryKeyBaseColumns());
			CollectionTools.addAll(this.foreignKeyColumns, relation.getForeignKey().baseColumns());
			String attributeName = this.configureAttributeName(relation.getAttributeName());
			relation.setMappedBy(attributeName);
			this.manyToOneAttributeNames.put(relation, attributeName);
		}
	}

	/**
	 * Build a unique attribute name for the specified "basic" columns,
	 * checking for name collisions.
	 * Store the calculated names so we can get them back later, when we
	 * are generating source.
	 */
	private void buildBasicAttributeNames(Set<Column> columns) {
		for (Column column : columns) {
			String attributeName = this.configureAttributeName(column.getName());
			this.basicAttributeNames.put(column, attributeName);
		}
	}

	private void buildOneToManyAttributeNames() {
		for (OneToManyRelation relation : this.oneToManyRelations) {
			String attributeName = this.configureAttributeName(relation.getAttributeName());
			this.oneToManyAttributeNames.put(relation, attributeName);
		}
	}

	private void buildOwnedManyToManyAttributeNames() {
		for (ManyToManyRelation relation : this.ownedManyToManyRelations) {
			String attributeName = this.configureAttributeName(relation.getOwnedAttributeName());
			relation.setMappedBy(attributeName);
			this.ownedManyToManyAttributeNames.put(relation, attributeName);
		}
	}

	private void buildNonOwnedManyToManyAttributeNames() {
		for (ManyToManyRelation relation : this.nonOwnedManyToManyRelations) {
			String attributeName = this.configureAttributeName(relation.getNonOwnedAttributeName());
			this.nonOwnedManyToManyAttributeNames.put(relation, attributeName);
		}
	}

	/**
	 * Convert the specified attribute name to something unique for the entity,
	 * converting it to something Java-like if the config flag is set.
	 * Store the calculated name to prevent future name collisions.
	 */
	private String configureAttributeName(String attributeName) {
		String result = attributeName;
		if (this.getEntityConfig().convertToJavaStyleIdentifiers()) {
			result = EntityGenTools.convertToUniqueJavaStyleAttributeName(result, this.attributeNames);
		} else {
			// first, convert the attribute name to a legal Java identifier
			result = NameTools.convertToJavaIdentifier(result);
			// then make sure it's unique
			result = NameTools.uniqueNameForIgnoreCase(attributeName, this.attributeNames);
		}
		this.attributeNames.add(result);
		return result;
	}

	@Override
	public String toString() {
		return StringTools.buildToStringFor(this, this.table);
	}

}
