/*******************************************************************************
 * 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.Iterator;
import java.util.List;

import org.eclipse.datatools.connectivity.sqm.core.rte.ICatalogObject;
import org.eclipse.datatools.modelbase.sql.constraints.PrimaryKey;
import org.eclipse.datatools.modelbase.sql.tables.BaseTable;
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.ArrayIterator;
import org.eclipse.jpt.utility.internal.iterators.TransformationIterator;

/**
 *  Wrap a DTP Table
 */
final class DTPTableWrapper
	extends DTPWrapper
	implements Table
{
	// backpointer to parent
	private final DTPSchemaWrapper schema;

	// the wrapped DTP table
	private final org.eclipse.datatools.modelbase.sql.tables.Table dtpTable;

	// lazy-initialized
	private DTPColumnWrapper[] columns;

	// lazy-initialized
	private DTPColumnWrapper[] primaryKeyColumns;

	// lazy-initialized
	private DTPForeignKeyWrapper[] foreignKeys;


	private static final DTPColumnWrapper[] EMPTY_COLUMNS = new DTPColumnWrapper[0];
	private static final DTPForeignKeyWrapper[] EMPTY_FOREIGN_KEYS = new DTPForeignKeyWrapper[0];


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

	DTPTableWrapper(DTPSchemaWrapper schema, org.eclipse.datatools.modelbase.sql.tables.Table dtpTable) {
		super(schema);
		this.schema = schema;
		this.dtpTable = dtpTable;
	}


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

	@Override
	ICatalogObject getCatalogObject() {
		return (ICatalogObject) this.dtpTable;
	}

	@Override
	synchronized void catalogObjectChanged(int eventType) {
		// clear stuff so it can be rebuilt
		this.dispose_();
		this.getConnectionProfile().tableChanged(this, eventType);
	}


	// ********** Table implementation **********

	@Override
	public String getName() {
		return this.dtpTable.getName();
	}

	public String getShortJavaClassName() {
		String jName = this.getName();
		if ( ! this.isCaseSensitive()) {
			jName = StringTools.capitalize(jName.toLowerCase());
		}
		return NameTools.convertToJavaIdentifier(jName);
	}

	public boolean matchesShortJavaClassName(String shortJavaClassName) {
		return this.isCaseSensitive() ?
			this.getName().equals(shortJavaClassName)
		:
			this.getName().equalsIgnoreCase(shortJavaClassName);
	}

	public String getJavaFieldName() {
		String jName = this.getName();
		if ( ! this.isCaseSensitive()) {
			jName = jName.toLowerCase();
		}
		return NameTools.convertToJavaIdentifier(jName);
	}

	// ***** columns

	public Iterator<Column> columns() {
		return new ArrayIterator<Column>(this.columns_());
	}

	private Iterator<DTPColumnWrapper> columnWrappers() {
		return new ArrayIterator<DTPColumnWrapper>(this.columns_());
	}

	private synchronized DTPColumnWrapper[] columns_() {
		if (this.columns == null) {
			this.columns = this.buildColumns();
		}
		return this.columns;
	}

	private DTPColumnWrapper[] buildColumns() {
		List<org.eclipse.datatools.modelbase.sql.tables.Column> dtpColumns = this.dtpColumns();
		DTPColumnWrapper[] result = new DTPColumnWrapper[dtpColumns.size()];
		for (int i = result.length; i-- > 0;) {
			result[i] = new DTPColumnWrapper(this, dtpColumns.get(i));
		}
		return result;
	}

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

	public int columnsSize() {
		return this.columns_().length;
	}

	public Iterator<String> columnNames() {
		return new TransformationIterator<DTPColumnWrapper, String>(this.columnWrappers()) {
			@Override
			protected String transform(DTPColumnWrapper next) {
				 return next.getName();
			}
		};
	}

	public boolean containsColumnNamed(String name) {
		return this.columnNamed(name) != null;
	}

	public DTPColumnWrapper columnNamed(String name) {
		return this.isCaseSensitive() ? this.columnNamedCaseSensitive(name) : this.columnNamedIgnoreCase(name);
	}

	private DTPColumnWrapper columnNamedCaseSensitive(String name) {
		for (Iterator<DTPColumnWrapper> stream = this.columnWrappers(); stream.hasNext(); ) {
			DTPColumnWrapper column = stream.next();
			if (column.getName().equals(name)) {
				return column;
			}
		}
		return null;
	}

	private DTPColumnWrapper columnNamedIgnoreCase(String name) {
		for (Iterator<DTPColumnWrapper> stream = this.columnWrappers(); stream.hasNext(); ) {
			DTPColumnWrapper column = stream.next();
			if (StringTools.stringsAreEqualIgnoreCase(column.getName(), name)) {
				return column;
			}
		}
		return null;
	}

	/**
	 * return the column for the specified DTP column
	 */
	DTPColumnWrapper column(org.eclipse.datatools.modelbase.sql.tables.Column dtpColumn) {
		if (dtpColumn.getTable() != this.dtpTable) {
			return this.schema.column(dtpColumn);
		}
		for (DTPColumnWrapper column : this.columns_()) {
			if (column.wraps(dtpColumn)) {
				return column;
			}
		}
		throw new IllegalArgumentException("invalid DTP column: " + dtpColumn);  //$NON-NLS-1$
	}

	// ***** primaryKeyColumns

	public Iterator<Column> primaryKeyColumns() {
		return new ArrayIterator<Column>(this.primaryKeyColumns_());
	}

	public DTPColumnWrapper primaryKeyColumn() {
		DTPColumnWrapper[] pkColumns = this.primaryKeyColumns_();
		if (pkColumns.length != 1) {
			throw new IllegalStateException("multiple primary key columns: " + pkColumns.length);  //$NON-NLS-1$
		}
		return pkColumns[0];
	}

	private synchronized DTPColumnWrapper[] primaryKeyColumns_() {
		if (this.primaryKeyColumns == null) {
			this.primaryKeyColumns = this.buildPrimaryKeyColumns();
		}
		return this.primaryKeyColumns;
	}

	private DTPColumnWrapper[] buildPrimaryKeyColumns() {
		if ( ! (this.dtpTable instanceof BaseTable)) {
			return EMPTY_COLUMNS;
		}
		PrimaryKey pk = ((BaseTable) this.dtpTable).getPrimaryKey();
		if (pk == null) {
			// no PK was defined
			return EMPTY_COLUMNS;
		}
		List<org.eclipse.datatools.modelbase.sql.tables.Column> pkColumns = this.columns(pk);
		DTPColumnWrapper[] result = new DTPColumnWrapper[pkColumns.size()];
		for (int i = result.length; i-- > 0;) {
			result[i] = this.column(pkColumns.get(i));
		}
		return result;
	}

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

	public int primaryKeyColumnsSize() {
		return this.primaryKeyColumns_().length;
	}

	public boolean primaryKeyColumnsContains(Column column) {
		return CollectionTools.contains(this.primaryKeyColumns_(), column);
	}

	// ***** foreignKeys

	public Iterator<ForeignKey> foreignKeys() {
		return new ArrayIterator<ForeignKey>(this.foreignKeys_());
	}

	private Iterator<DTPForeignKeyWrapper> foreignKeyWrappers() {
		return new ArrayIterator<DTPForeignKeyWrapper>(this.foreignKeys_());
	}

	private synchronized DTPForeignKeyWrapper[] foreignKeys_() {
		if (this.foreignKeys == null) {
			this.foreignKeys = this.buildForeignKeys();
		}
		return this.foreignKeys;
	}

	private DTPForeignKeyWrapper[] buildForeignKeys() {
		if ( ! (this.dtpTable instanceof BaseTable)) {
			return EMPTY_FOREIGN_KEYS;
		}
		List<org.eclipse.datatools.modelbase.sql.constraints.ForeignKey> dtpForeignKeys = this.dtpForeignKeys();
		DTPForeignKeyWrapper[] result = new DTPForeignKeyWrapper[dtpForeignKeys.size()];
		for (int i = result.length; i-- > 0;) {
			result[i] = new DTPForeignKeyWrapper(this, dtpForeignKeys.get(i));
		}
		return result;
	}

	@SuppressWarnings("unchecked")
	private List<org.eclipse.datatools.modelbase.sql.constraints.ForeignKey> dtpForeignKeys() {
		return ((BaseTable) this.dtpTable).getForeignKeys();
	}

	public int foreignKeysSize() {
		return this.foreignKeys_().length;
	}

	public boolean foreignKeyBaseColumnsContains(Column column) {
		for (Iterator<DTPForeignKeyWrapper> stream = this.foreignKeyWrappers(); stream.hasNext(); ) {
			DTPForeignKeyWrapper foreignKey = stream.next();
			if (foreignKey.baseColumnsContains(column)) {
				return true;
			}
		}
		return false;
	}


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

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


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

	boolean wraps(org.eclipse.datatools.modelbase.sql.tables.Table table) {
		return this.dtpTable == table;
	}

	boolean isCaseSensitive() {
		return this.schema.isCaseSensitive();
	}

	DTPTableWrapper table(org.eclipse.datatools.modelbase.sql.tables.Table table) {
		return this.schema.table(table);
	}

	DTPDatabaseWrapper database() {
		return this.schema.database();
	}


	// ********** disposal **********

	@Override
	synchronized void dispose() {
		this.dispose_();
		super.dispose();
	}

	private void dispose_() {
		this.disposeForeignKeys();
		// the table does not "contain" the pk columns, so no need to forward #dispose()
		this.primaryKeyColumns = null;
		this.disposeColumns();
	}

	private void disposeForeignKeys() {
		if (this.foreignKeys != null) {
			for (DTPForeignKeyWrapper foreignKey : this.foreignKeys) {
				foreignKey.dispose();
			}
	    	this.foreignKeys = null;
		}
	}

	private void disposeColumns() {
		if (this.columns != null) {
			for (DTPColumnWrapper column : this.columns) {
				column.dispose();
			}
	    	this.columns = null;
		}
	}

}
