/*******************************************************************************
 * Copyright (c) 2007, 2008 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.internal2;

import java.util.List;

import org.eclipse.jpt.db.ForeignKey;
import org.eclipse.jpt.gen.internal2.util.StringUtil;

/**
 * Represents an ORM association.
 * There are two types of associations:
 * <ul><li>simple association: An association between two database tables.
 * The <em>referrer</code> table is the one containing the foreign key
 * , the <em>referenced</code> table is the other party.<br>
 * 
 * <li>many to many association: An association between two tables joined by 
 * a <em>join table</em>.
 * In the example AUTHOR, BOOK, AUTHOR_BOOK, The referrer and referenced are 
 * AUTHOR and  BOOK, and the join table is AUTHOR_BOOK.
 * </ul>
 * 
 */
public class Association implements java.io.Serializable
{
	private final static long serialVersionUID = 2;

	public static final String MANY_TO_ONE = "many-to-one";
	public static final String MANY_TO_MANY = "many-to-many";
	public static final String ONE_TO_ONE = "one-to-one";
	public static final String ONE_TO_MANY = "one-to-many";
	
	public static final String BI_DI = "bi-di";
	public static final String NORMAL_DI = "normal-di"; //referrer->referenced
	public static final String OPPOSITE_DI = "opposite-di"; //referenced->referrer
	
	private transient ORMGenCustomizer mCustomizer;
	private String mReferrerTableName;
	private String mReferencedTableName;
	private String mJoinTableName;

	private List<String> mReferrerColNames; /*String objects*/
	private List<String> mReferencedColNames; /*String objects*/
	private List<String> mReferrerJoinColNames; /*String objects*/
	private List<String> mReferencedJoinColNames; /*String objects*/

	private transient List<ORMGenColumn> mReferrerCols; /*ORMGenColumn objects*/
	private transient List<ORMGenColumn> mReferencedCols; /*ORMGenColumn objects*/
	private transient List<ORMGenColumn> mReferrerJoinCols; /*ORMGenColumn objects*/
	private transient List<ORMGenColumn> mReferencedJoinCols; /*ORMGenColumn objects*/
	
	private String mCardinality;
	private String mDirectionality;
	private byte mFlags = GENERATED;
	
	private AssociationRole mReferrerRole;
	private AssociationRole mReferencedRole;

	private transient ForeignKey mForeignKey;	
	
	/*constants for mFlags*/
	/*whether the association should be generated*/
	private static final byte GENERATED = 1 << 0;
	/*whether the association is custom (i.e is not auto computed from foreign keys relationships).*/
	private static final byte CUSTOM = 1 << 1;
	
	/**
	 * The simple association constructor.
	 * The 2 tables are joined when the values of each column in
	 * referrerColNames match its corresponding column in referencedColNames.
	 * 
	 * @param referrerTableName The "foreign key" table.
	 * @param referrerColNames The column names in the referrer table.
	 * @param referencedTableName The "primary key" table.
	 * @param referencedColNames The column names in the referenced table.
	 */
	public Association(ORMGenCustomizer customizer, String referrerTableName, List<String> referrerColNames
			, String referencedTableName, List<String> referencedColNames)  {
		super();
		
		mCustomizer = customizer;
		mReferrerTableName = referrerTableName;
		mReferencedTableName = referencedTableName;
		mReferrerColNames = referrerColNames;
		mReferencedColNames = referencedColNames;
		
		mCardinality = MANY_TO_ONE;
		mDirectionality = BI_DI;
		
		setCustom(true);
	}
	/**
	 * The many to many constructor.
	 * The 2 tables are joined when the values of each column in
	 * referrerColNames match its corresponding column in referrerJoinColNames
	 * , and each column in referencedColNames match its corresponding column in referencedJoinColNames.
	 *
	 */
	public Association(ORMGenCustomizer customizer, String referrerTableName, List<String> referrerColNames
			, String referencedTableName, List<String> referencedColNames
			, String joinTableName, List<String> referrerJoinColNames, List<String> referencedJoinColNames) {
		super();
		
		mCustomizer = customizer;
		mReferrerTableName = referrerTableName;
		mReferencedTableName = referencedTableName;
		mReferrerColNames = referrerColNames;
		mReferencedColNames = referencedColNames;
		mJoinTableName = joinTableName;
		mReferrerJoinColNames = referrerJoinColNames;
		mReferencedJoinColNames = referencedJoinColNames;
		
		mCardinality = MANY_TO_MANY;	
		mDirectionality = BI_DI;
		
		setCustom(true);
	}
	/**
	 * Empty constructor needed by the deserialization (should not be used otherwise).
	 */
	public Association() {
	}
	/**
	 * Computes the cardinality basedon the forign key definitions.
	 */
	public void computeCardinality()  {
		/*by default the association is many-to-one unless the foreign key 
		 * is also the primary key, in which case it is a one-to-one.*/
		mCardinality = MANY_TO_ONE;
		
		List<ORMGenColumn> referrerCols = getReferrerColumns();
		List<ORMGenColumn> pkCols = getReferrerTable().getPrimaryKeyColumns();
		if (pkCols.size() == referrerCols.size()) {
			boolean isFkPk = true;
			for (int i = 0, n = pkCols.size(); i < n; ++i) {
				if (!((ORMGenColumn)pkCols.get(i)).getName().equals(((ORMGenColumn)referrerCols.get(i)).getName())) {
					isFkPk = false;
					break;
				}
			}
			if (isFkPk) {
				mCardinality = ONE_TO_ONE;
			}
		}
		
		setCustom(false);
	}
	/**
	 * Called after the asscociations are deserialized to attach 
	 * the customizer object.
	 */
	protected void restore(ORMGenCustomizer customizer) {
		mCustomizer = customizer;
		
		if (mReferrerRole != null) {
			mReferrerRole.restore(this);
		}
		if (mReferencedRole != null) {
			mReferencedRole.restore(this);
		}
	}
	public ORMGenTable getReferrerTable()  {
		return mCustomizer.getTable(mReferrerTableName);
	}
	public String getReferrerTableName() {
		return mReferrerTableName;
	}
	public ORMGenTable getReferencedTable()  {
		return mCustomizer.getTable(mReferencedTableName);
	}
	public String getReferencedTableName() {
		return mReferencedTableName;
	}
	public ORMGenTable getJoinTable()  {
		return mCustomizer.getTable(mJoinTableName);
	}
	public String getJoinTableName() {
		return mJoinTableName;
	}
	/**
	 * Returns the <code>ORMGenColumn</code> objects for the referrer
	 * columns.
	 */
	public List<ORMGenColumn> getReferrerColumns() {
		if (mReferrerCols == null) {
			mReferrerCols = getReferrerTable().getColumnsByNames(mReferrerColNames);
		}
		return mReferrerCols;
	}
	public List<String> getReferrerColumnNames() {
		return mReferrerColNames;
	}
	/**
	 * Returns the <code>ORMGenColumn</code> objects for the referenced
	 * columns.
	 */
	public List<ORMGenColumn> getReferencedColumns() {
		if (mReferencedCols == null) {
			mReferencedCols = getReferencedTable().getColumnsByNames(mReferencedColNames);
		}
		return mReferencedCols;
	}
	public List<String> getReferencedColumnNames() {
		return mReferencedColNames;
	}
	public List<ORMGenColumn> getReferrerJoinColumns() {
		if (mReferrerJoinCols == null) {
			mReferrerJoinCols = getJoinTable().getColumnsByNames(mReferrerJoinColNames);
		}
		return mReferrerJoinCols;
	}
	public List<String> getReferrerJoinColumnNames() {
		return mReferrerJoinColNames;
	}
	public List<ORMGenColumn> getReferencedJoinColumns()  {
		if (mReferencedJoinCols == null) {
			mReferencedJoinCols = getJoinTable().getColumnsByNames(mReferencedJoinColNames);
		}
		return mReferencedJoinCols;
	}
	public List<String> getReferencedJoinColumnNames() {
		return mReferencedJoinColNames;
	}
	/**
	 * Returns the association cardinality, one of {@link #MANY_TO_ONE}|{@link #MANY_TO_MANY}
	 * |{@link #ONE_TO_ONE}|{@link #ONE_TO_MANY}
	 */
	public String getCardinality() {
		return mCardinality;
	}
	public void setCardinality(String cardinality) {
		assert(cardinality.equals(MANY_TO_ONE) || cardinality.equals(MANY_TO_MANY) || cardinality.equals(ONE_TO_ONE) || cardinality.equals(ONE_TO_MANY));
		mCardinality = cardinality;
	}
	/**
	 * Returns the association directionality, one of {@link #BI_DI}|{@link #NORMAL_DI}
	 * |{@link #OPPOSITE_DI}
	 */
	public String getDirectionality() {
		return mDirectionality;
	}
	public void setDirectionality(String dir) {
		assert(dir.equals(BI_DI) || dir.equals(NORMAL_DI) || dir.equals(OPPOSITE_DI));
		if (!dir.equals(mDirectionality)) {
			mDirectionality = dir;
			
			if (dir.equals(NORMAL_DI)) {
				mReferencedRole = null;
			} else if (dir.equals(OPPOSITE_DI)) {
				mReferrerRole = null;
			}
		}
	}
	
	/**
	 * Tests whether this association is bidirectional.
	 * This is a shortcut for <code>getDirectionality().equals(BI_DI)</code>.
	 */
	public boolean isBidirectional() {
		return mDirectionality.equals(BI_DI);
	}
	/**
	 * Returns true of this association should be generated. 
	 */
	public boolean isGenerated() {
		return (mFlags & GENERATED) != 0;
	}
	public void setGenerated(boolean generated) {
		if (generated != isGenerated()) {
			if (generated) {
				mFlags |= GENERATED;
			} else {
				mFlags &= ~GENERATED;
			}
			mReferrerRole = mReferencedRole = null;
		}
	}
	/**
	 * Returns true of this association is custom (i.e is not auto computed from foreign keys relationships). 
	 */
	public boolean isCustom() {
		return (mFlags & CUSTOM) != 0;
	}
	public void setCustom(boolean custom) {
		if (custom) {
			mFlags |= CUSTOM;
		} else {
			mFlags &= ~CUSTOM;
		}
	}
	/**
	 * Returns the association role for the referrer side, or null 
	 * if none (i.e if the directionality does not include it).
	 */
	public AssociationRole getReferrerRole() {
		if (mReferrerRole == null && isGenerated()) {
			if (!getDirectionality().equals(OPPOSITE_DI)) { //BI_DI or NORMAL_DI
				mReferrerRole = new AssociationRole(this, true/*isReferrerEnd*/);
			}
		}
		return mReferrerRole;
	}
	/**
	 * Returns the association role for the referenced side, or null 
	 * if none (i.e if the directionality does not include it).
	 */
	public AssociationRole getReferencedRole() {
		if (mReferencedRole == null && isGenerated()) {
			if (!getDirectionality().equals(Association.NORMAL_DI)) { //BI_DI or OPPOSITE_DI
				mReferencedRole = new AssociationRole(this, false/*isReferrerEnd*/);
			}
		}
		return mReferencedRole;
	}
	/**
	 * Tests whether this association is valid (valid table and column names).
	 */
	protected boolean isValid(){
		if (!isValidTableAndColumns(mReferrerTableName, mReferrerColNames)
				|| !isValidTableAndColumns(mReferencedTableName, mReferencedColNames)) {
			return false;
		}
		if (mJoinTableName != null) {
			if (!isValidTableAndColumns(mJoinTableName, mReferrerJoinColNames)
					|| !isValidTableAndColumns(mJoinTableName, mReferencedJoinColNames)) {
				return false;
			}			
		}
		return true;
	}
	private boolean isValidTableAndColumns(String tableName, List<String> columnNames) {
		ORMGenTable table = mCustomizer.getTable(tableName);
		if (table == null) {
			return false;
		}
		for (int i = 0, n = columnNames.size(); i < n; ++i) {
			String colName = (String)columnNames.get(i);
			if (table.getColumnByName(colName) == null) {
				return false;
			}
		}
		return true;
	}
	
	public void setForeignKey(ForeignKey foreignKey) {
		this.mForeignKey = foreignKey;
		
	}
	public ForeignKey getForeignKey(){
		return this.mForeignKey;
	};	
	public boolean equals(Object obj) {
		if( this == obj )
			return true;
		if( obj instanceof Association ){
			Association association2 = (Association)obj;
			if (!this.getReferrerTableName().equals(association2.getReferrerTableName())
					|| !this.getReferencedTableName().equals(association2.getReferencedTableName())
					|| !StringUtil.equalObjects(this.getJoinTableName(), association2.getJoinTableName())
					|| !this.getReferrerColumnNames().equals(association2.getReferrerColumnNames())
					|| !this.getReferencedColumnNames().equals(association2.getReferencedColumnNames())
					) {
				return false;
			}					
			/*the 2 association have the same referrer, referenced and join table*/
			//If MTO or OTM association
			if (this.getJoinTableName() == null) {
				return true;
			}
			if (this.getReferrerJoinColumnNames().equals(association2.getReferrerJoinColumnNames())
					&& this.getReferencedJoinColumnNames().equals(association2.getReferencedJoinColumnNames())) {
				return true;
			}
		}
		return false;
	}	
	public String toString(){
		return mReferrerTableName + " " + mCardinality + " " + mReferencedTableName ;
	}
}
