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

import java.text.Collator;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import org.eclipse.jpt.db.Column;
import org.eclipse.jpt.db.ForeignKey;
import org.eclipse.jpt.utility.internal.CollectionTools;
import org.eclipse.jpt.utility.internal.StringTools;
import org.eclipse.jpt.utility.internal.iterators.ArrayIterator;
import org.eclipse.jpt.utility.internal.iterators.FilteringIterator;
import org.eclipse.jpt.utility.internal.iterators.TransformationIterator;

/**
 *  Wrap a DTP ForeignKey
 */
final class DTPForeignKeyWrapper
	extends DTPDatabaseObjectWrapper
	implements ForeignKey
{
	// the wrapped DTP foreign key
	private final org.eclipse.datatools.modelbase.sql.constraints.ForeignKey dtpForeignKey;

	// lazy-initialized
	private DTPTableWrapper referencedTable;

	// lazy-initialized
	private LocalColumnPair[] columnPairs;

	// lazy-initialized - but it can be 'null' so we use a flag
	private String defaultAttributeName;
	private boolean defaultAttributeNameCalculated = false;


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

	DTPForeignKeyWrapper(DTPTableWrapper baseTable, org.eclipse.datatools.modelbase.sql.constraints.ForeignKey dtpForeignKey) {
		super(baseTable, dtpForeignKey);
		this.dtpForeignKey = dtpForeignKey;
	}


	// ********** DTPWrapper implementation **********

	@Override
	synchronized void catalogObjectChanged() {
		super.catalogObjectChanged();
		this.getConnectionProfile().foreignKeyChanged(this);
	}

	@Override
	public String toString() {
		return StringTools.buildToStringFor(this, this.getName() + ": " + Arrays.asList(this.getColumnPairs()));  //$NON-NLS-1$
	}


	// ********** ForeignKey implementation **********

	public String getName() {
		return this.dtpForeignKey.getName();
	}

	public DTPTableWrapper getBaseTable() {
		return (DTPTableWrapper) this.getParent();
	}

	public synchronized DTPTableWrapper getReferencedTable() {
		if (this.referencedTable == null) {
			this.referencedTable = this.getBaseTable().getTable(this.dtpForeignKey.getUniqueConstraint().getBaseTable());
		}
		return this.referencedTable;
	}

	public boolean referencesSingleColumnPrimaryKey() {
		if (this.columnPairsSize() != 1) {
			return false;
		}
		if (this.getReferencedTable().primaryKeyColumnsSize() != 1) {
			return false;
		}
		return this.getColumnPair().getReferencedColumn() == this.getReferencedTable().getPrimaryKeyColumn();
	}

	// ***** column pairs

	public Iterator<ColumnPair> columnPairs() {
		return new ArrayIterator<ColumnPair>(this.getColumnPairs());
	}

	public LocalColumnPair getColumnPair() {
		LocalColumnPair[] pairs = this.getColumnPairs();
		if (pairs.length != 1) {
			throw new IllegalStateException("multiple column pairs: " + pairs.length);  //$NON-NLS-1$
		}
		return pairs[0];
	}

	private Iterator<LocalColumnPair> localColumnPairs() {
		return new ArrayIterator<LocalColumnPair>(this.getColumnPairs());
	}

	private synchronized LocalColumnPair[] getColumnPairs() {
		if (this.columnPairs == null) {
			this.columnPairs = this.buildColumnPairs();
		}
		return this.columnPairs;
	}

	private LocalColumnPair[] buildColumnPairs() {
		List<org.eclipse.datatools.modelbase.sql.tables.Column> baseColumns = this.getDTPBaseColumns();
		int size = baseColumns.size();
		List<org.eclipse.datatools.modelbase.sql.tables.Column> refColumns = this.getDTPReferenceColumns();
		if (refColumns.size() != size) {
			throw new IllegalStateException(this.getBaseTable().getName() + '.' + this.getName() +
								" - mismatched sizes: " + size + " vs. " + refColumns.size());  //$NON-NLS-1$  //$NON-NLS-2$
		}
		LocalColumnPair[] result = new LocalColumnPair[baseColumns.size()];
		for (int i = baseColumns.size(); i-- > 0; ) {
			result[i] = new LocalColumnPair(
								this.getBaseTable().getColumn(baseColumns.get(i)),
								this.getBaseTable().getColumn(refColumns.get(i))
						);
		}
		return result;
	}

	// minimize scope of suppressed warnings
	@SuppressWarnings("unchecked")
	private List<org.eclipse.datatools.modelbase.sql.tables.Column> getDTPBaseColumns() {
		return this.dtpForeignKey.getMembers();
	}

	// minimize scope of suppressed warnings
	@SuppressWarnings("unchecked")
	private List<org.eclipse.datatools.modelbase.sql.tables.Column> getDTPReferenceColumns() {
		return this.dtpForeignKey.getUniqueConstraint().getMembers();
	}

	public int columnPairsSize() {
		return this.getColumnPairs().length;
	}

	public Iterator<Column> baseColumns() {
		return new TransformationIterator<LocalColumnPair, Column>(this.localColumnPairs()) {
			@Override
			protected Column transform(LocalColumnPair pair) {
				return pair.getBaseColumn();
			}
		};
	}

	boolean baseColumnsContains(Column column) {
		return CollectionTools.contains(this.baseColumns(), column);
	}

	public Iterator<Column> nonPrimaryKeyBaseColumns() {
		return new FilteringIterator<Column, Column>(this.baseColumns()) {
			@Override
			protected boolean accept(Column column) {
				return ! column.isPartOfPrimaryKey();
			}
		};
	}

	public Iterator<Column> referencedColumns() {
		return new TransformationIterator<LocalColumnPair, Column>(this.localColumnPairs()) {
			@Override
			protected Column transform(LocalColumnPair columnPair) {
				return columnPair.getReferencedColumn();
			}
		};
	}

	// ***** attribute name

	public String getAttributeName() {
		String defaultName = this.getDefaultAttributeName();
		return (defaultName != null) ? defaultName : this.getNonDefaultAttributeName();
	}

	public synchronized String getDefaultAttributeName() {
		if ( ! this.defaultAttributeNameCalculated) {
			this.defaultAttributeNameCalculated = true;
			this.defaultAttributeName = this.buildDefaultAttributeName();
		}
		return this.defaultAttributeName;
	}

	private String buildDefaultAttributeName() {
		if ( ! this.referencesSingleColumnPrimaryKey()) {
			return null;
		}
		LocalColumnPair columnPair = this.getColumnPair();
		String baseColName = columnPair.getBaseColumn().getName();
		String refColName = columnPair.getReferencedColumn().getName();
		if (baseColName.length() <= (refColName.length() + 1)) {
			return null;
		}
		if ( ! baseColName.endsWith(refColName)) {
			return null;
		}
		int _index = baseColName.length() - refColName.length() - 1;
		if (baseColName.charAt(_index) != '_') {
			return null;
		}
		return baseColName.substring(0, _index);
	}

	/**
	 * If this is a simple (single-column) foreign key, use the name of the
	 * single base column to build a name. If this is a compound foreign key,
	 * return the name of the referenced table.
	 */
	// TODO if there is only one FK to a given table, use the table's name instead of the column's name?
	private String getNonDefaultAttributeName() {
		return (this.columnPairsSize() == 1) ?
						this.getNonDefaultAttributeNameFromBaseColumn()
					:
						this.getReferencedTable().getName();
	}

	/**
	 * The underscore check is helpful when the referenced column is NOT the
	 * primary key of the referenced table (i.e. it has only a UNIQUE constraint).
	 *     ForeignKey(EMP.CUBICLE_ID => CUBICLE.ID) => "CUBICLE"
	 *     ForeignKey(EMP.CUBICLEID => CUBICLE.ID) => "CUBICLE"
	 *     ForeignKey(EMP.CUBICLE_PK => CUBICLE.ID) => "CUBICLE_PK"
	 */
	private String getNonDefaultAttributeNameFromBaseColumn() {
		LocalColumnPair columnPair = this.getColumnPair();
		String baseColName = columnPair.getBaseColumn().getName();
		String refColName = columnPair.getReferencedColumn().getName();
		int len = baseColName.length();
		int refLen = refColName.length();
		if ((len > refLen) && baseColName.endsWith(refColName)) {
			len = len - refLen;
			if ((len > 1) && baseColName.charAt(len - 1) == '_') {
				len = len - 1;
			}
		}
		return baseColName.substring(0, len);
	}

	/**
	 * Examples:
	 * Oracle etc.
	 *     ForeignKey(FOO_ID => ID) vs. "foo" => null
	 *     ForeignKey(FOO_ID => FOO_ID) vs. "foo" => "FOO_ID"
	 *     ForeignKey(FOO => ID) vs. "foo" => "FOO"
	 *     ForeignKey(Foo_ID => ID) vs. "foo" => "\"Foo_ID\""
	 *     
	 * PostgreSQL etc.
	 *     ForeignKey(foo_id => id) vs. "foo" => null
	 *     ForeignKey(foo_id => foo_id) vs. "foo" => "foo_id"
	 *     ForeignKey(foo => id) vs. "foo" => "foo"
	 *     ForeignKey(Foo_ID => ID) vs. "foo" => "\"Foo_ID\""
	 *     
	 * SQL Server etc.
	 *     ForeignKey(foo_ID => ID) vs. "foo" => null
	 *     ForeignKey(FOO_ID => FOO_ID) vs. "foo" => "FOO_ID"
	 *     ForeignKey(FOO => ID) vs. "foo" => "FOO"
	 *     ForeignKey(Foo_ID => ID) vs. "foo" => "Foo_ID"
	 */
	public String getJoinColumnAnnotationIdentifier(String attributeName) {
		String baseColumnName = this.getColumnPair().getBaseColumn().getName();
		String defaultBaseColumnName = attributeName + '_' + this.getReferencedTable().getPrimaryKeyColumn().getName();
		return this.getDatabase().convertNameToIdentifier(baseColumnName, defaultBaseColumnName);
	}


	// ********** Comparable implementation **********

	public int compareTo(ForeignKey foreignKey) {
		return Collator.getInstance().compare(this.getName(), foreignKey.getName());
	}


	// ********** internal methods **********

	boolean wraps(org.eclipse.datatools.modelbase.sql.constraints.ForeignKey foreignKey) {
		return this.dtpForeignKey == foreignKey;
	}

	@Override
	void clear() {
		// the foreign key does not "contain" any other objects,
		// so we don't need to forward the #clear()
		this.defaultAttributeNameCalculated = false;
		this.defaultAttributeName = null;
		this.columnPairs =  null;
		this.referencedTable = null;
	}


	// ********** column pair implementation **********

	private static class LocalColumnPair implements ColumnPair {
		private final DTPColumnWrapper baseColumn;
		private final DTPColumnWrapper referencedColumn;

		LocalColumnPair(DTPColumnWrapper baseColumn, DTPColumnWrapper referencedColumn) {
			super();
			if ((baseColumn == null) || (referencedColumn == null)) {
				throw new NullPointerException();
			}
			this.baseColumn = baseColumn;
			this.referencedColumn = referencedColumn;
		}

		public DTPColumnWrapper getBaseColumn() {
			return this.baseColumn;
		}

		public DTPColumnWrapper getReferencedColumn() {
			return this.referencedColumn;
		}

		public int compareTo(ColumnPair columnPair) {
			return Collator.getInstance().compare(this.getBaseColumn().getName(), columnPair.getBaseColumn().getName());
		}

		@Override
		public String toString() {
			return StringTools.buildToStringFor(this, this.baseColumn.getName() + "=>" + this.referencedColumn.getName());  //$NON-NLS-1$
		}

	}

}
