/*******************************************************************************
 * Copyright (c) 2006, 2012 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.jpa.core.internal.context;

import org.eclipse.core.resources.IResource;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IType;
import org.eclipse.jpt.common.core.internal.resource.java.source.SourceNode;
import org.eclipse.jpt.common.core.internal.utility.JDTTools;
import org.eclipse.jpt.common.core.resource.java.JavaResourceNode;
import org.eclipse.jpt.common.utility.internal.ArrayTools;
import org.eclipse.jpt.common.utility.internal.ClassName;
import org.eclipse.jpt.common.utility.internal.ReflectionTools;
import org.eclipse.jpt.common.utility.internal.Transformer;
import org.eclipse.jpt.jpa.core.context.AttributeMapping;
import org.eclipse.jpt.jpa.core.context.Column;
import org.eclipse.jpt.jpa.core.context.ColumnMapping;
import org.eclipse.jpt.jpa.core.context.Entity;
import org.eclipse.jpt.jpa.core.context.JoinColumn;
import org.eclipse.jpt.jpa.core.context.JoinTable;
import org.eclipse.jpt.jpa.core.context.PersistentType;
import org.eclipse.jpt.jpa.core.context.ReadOnlyAttributeOverride;
import org.eclipse.jpt.jpa.core.context.ReadOnlyJoinColumn;
import org.eclipse.jpt.jpa.core.context.ReadOnlyPersistentAttribute;
import org.eclipse.jpt.jpa.core.context.ReadOnlyRelationship;
import org.eclipse.jpt.jpa.core.context.ReferenceTable;
import org.eclipse.jpt.jpa.core.context.Relationship;
import org.eclipse.jpt.jpa.core.context.RelationshipMapping;
import org.eclipse.jpt.jpa.core.context.TypeMapping;
import org.eclipse.jpt.jpa.core.context.java.JavaJpaContextNode;
import org.eclipse.jpt.jpa.core.jpa2.context.AttributeMapping2_0;
import org.eclipse.jpt.jpa.core.jpa2.context.CollectionMapping2_0;
import org.eclipse.jpt.jpa.core.jpa2.context.ElementCollectionMapping2_0;
import org.eclipse.jpt.jpa.core.jpa2.context.MetamodelField;
import org.eclipse.jpt.jpa.db.Table;

/**
 * Gather some of the behavior common to the Java and XML models. :-(
 */
public final class MappingTools {

	/**
	 * Return whether the specified type is "basic".
	 * @param fullyQualifiedName may include array brackets but not generic type arguments
	 */
	public static boolean typeIsBasic(IJavaProject javaProject, String fullyQualifiedName) {
		if (fullyQualifiedName == null) {
			return false;
		}

		int arrayDepth = ReflectionTools.getArrayDepthForTypeDeclaration(fullyQualifiedName);
		if (arrayDepth > 1) {
			return false;  // multi-dimensional arrays are not supported
		}

		if (arrayDepth == 1) {
			String elementTypeName = ReflectionTools.getElementTypeNameForTypeDeclaration(fullyQualifiedName, 1);
			return elementTypeIsValidForBasicArray(elementTypeName);
		}

		// arrayDepth == 0
		if (ClassName.isVariablePrimitive(fullyQualifiedName)) {
			return true;  // any primitive but 'void'
		}
		if (ClassName.isVariablePrimitiveWrapper(fullyQualifiedName)) {
			return true;  // any primitive wrapper but 'java.lang.Void'
		}
		if (typeIsOtherValidBasicType(fullyQualifiedName)) {
			return true;
		}
		IType type = JDTTools.findType(javaProject, fullyQualifiedName);
		if (type == null) {
			return false;
		}
		if (JDTTools.typeIsSerializable(javaProject, type)) {
			return true;
		}
		if (JDTTools.typeIsEnum(type)) {
			return true;
		}
		return false;
	}

	/**
	 * Return whether the specified type is a valid element type for
	 * a one-dimensional array that can default to a basic mapping:<ul>
	 * <li><code>byte</code>
	 * <li><code>java.lang.Byte</code>
	 * <li><code>char</code>
	 * <li><code>java.lang.Character</code>
	 * </ul>
	 */
	public static boolean elementTypeIsValidForBasicArray(String elementTypeName) {
		return ArrayTools.contains(VALID_BASIC_ARRAY_ELEMENT_TYPE_NAMES, elementTypeName);
	}

	private static final String[] VALID_BASIC_ARRAY_ELEMENT_TYPE_NAMES = {
		byte.class.getName(),
		char.class.getName(),
		java.lang.Byte.class.getName(),
		java.lang.Character.class.getName()
	};

	/**
	 * Return whether the specified type is among the various "other" types
	 * that can default to a basic mapping.
	 */
	public static boolean typeIsOtherValidBasicType(String typeName) {
		return ArrayTools.contains(OTHER_VALID_BASIC_TYPE_NAMES, typeName);
	}

	private static final String[] OTHER_VALID_BASIC_TYPE_NAMES = {
		java.lang.String.class.getName(),
		java.math.BigInteger.class.getName(),
		java.math.BigDecimal.class.getName(),
		java.util.Date.class.getName(),
		java.util.Calendar.class.getName(),
		java.sql.Date.class.getName(),
		java.sql.Time.class.getName(),
		java.sql.Timestamp.class.getName(),
	};

	/**
	 * Default join table name from the JPA spec:<br>
	 * 	"The concatenated names of the two associated primary
	 * 	entity tables, separated by a underscore."
	 * <pre>
	 * [owning table name]_[target table name]
	 * </pre>
	 * <strong>NB:</strong> The <em>names</em> are concatenated,
	 * <em>not</em> the <em>identifiers</em>.
	 * E.g. the join table for <code>"Foo"</code> and <code>"baR"</code>
	 * (where the "delimited" identifier is required) is:
	 * <pre>
	 *     "Foo_baR"
	 * </pre>
	 * not
	 * <pre>
	 *     "Foo"_"baR"
	 * </pre>
	 * As a result, we cannot honestly calculate the default name without a
	 * database connection. We need the database to convert the resulting name
	 * to an identifier appropriate to the current database.
	 */
	public static String buildJoinTableDefaultName(ReadOnlyRelationship relationship) {
		if (relationship.getJpaProject().getDataSource().connectionProfileIsActive()) {
			return buildDbJoinTableDefaultName(relationship);
		}
		// continue with a "best effort":
		String owningTableName = relationship.getTypeMapping().getPrimaryTableName();
		if (owningTableName == null) {
			return null;
		}
		RelationshipMapping relationshipMapping = relationship.getMapping();
		if (relationshipMapping == null) {
			return null;
		}
		Entity targetEntity = relationshipMapping.getResolvedTargetEntity();
		if (targetEntity == null) {
			return null;
		}
		String targetTableName = targetEntity.getPrimaryTableName();
		if (targetTableName == null) {
			return null;
		}
		return owningTableName + '_' + targetTableName;
	}

	/**
	 * Use the database to build a more accurate default name.
	 */
	private static String buildDbJoinTableDefaultName(ReadOnlyRelationship relationship) {
		Table owningTable = relationship.getTypeMapping().getPrimaryDbTable();
		if (owningTable == null) {
			return null;
		}
		RelationshipMapping relationshipMapping = relationship.getMapping();
		if (relationshipMapping == null) {
			return null;
		}
		Entity targetEntity = relationshipMapping.getResolvedTargetEntity();
		if (targetEntity == null) {
			return null;
		}
		Table targetTable = targetEntity.getPrimaryDbTable();
		if (targetTable == null) {
			return null;
		}
		String name = owningTable.getName() + '_' + targetTable.getName();
		return owningTable.getDatabase().convertNameToIdentifier(name);
	}

	/**
	 * Default collection table name from the JPA spec:<br>
	 * 	"The concatenation of the name of the containing entity and
	 *  the name of the collection attribute, separated by an underscore."
	 * <pre>
	 * [owning entity name]_[attribute name]
	 * </pre>
	 */
	public static String buildCollectionTableDefaultName(ElementCollectionMapping2_0 mapping) {
		Entity entity = mapping.getEntity();
		if (entity == null) {
			return null;
		}
		String owningEntityName = entity.getName();
		String attributeName = mapping.getName();
		return owningEntityName + '_' + attributeName;
	}

	/**
	 * Return the join column's default name;
	 * which is typically<pre>
	 *     [attribute name]_[referenced column name]
	 * </pre>
	 * But, if we don't have an attribute name (e.g. in a unidirectional
	 * one-to-many or many-to-many) is<pre>
	 *     [target entity name]_[referenced column name]
	 * </pre>
	 * @see #buildJoinTableDefaultName(ReadOnlyRelationship)
	 */
	public static String buildJoinColumnDefaultName(ReadOnlyJoinColumn joinColumn, ReadOnlyJoinColumn.Owner owner) {
		if (owner.getJoinColumnsSize() != 1) {
			return null;
		}
		String prefix = owner.getAttributeName();
		if (prefix == null) {
			Entity targetEntity = owner.getRelationshipTarget();
			if (targetEntity == null) {
				return null;
			}
			prefix = targetEntity.getName();
		}
		// It's not clear which of these is correct....
		// The spec implies that the referenced column is always the
		// *primary key* column of the target entity; i.e. the primary key as
		// defined on the *database* (or, possibly, the primary key as defined
		// by the target entity's Id mapping?), not the name of the referenced
		// column irrespective of whether it is the primary key on the target
		// entity's table. But this seems like it would be wrong; since the
		// referenced column need not be a primary key and we don't always have
		// access to the database.
		//
		// Column targetColumn = joinColumn.getTargetPrimaryKeyDbColumn();
		String targetColumnName = joinColumn.getReferencedColumnName();
		if (targetColumnName == null) {
			return null;
		}
		String name = prefix + '_' + targetColumnName;
		// Again, it's not clear which of these is correct....
		// Converting the name to an identifier will result in the identifier
		// being delimited nearly every time (at least on non-Sybase/MS
		// databases); but that probably is not the intent of the spec....
		//
		// return targetColumn.getDatabase().convertNameToIdentifier(name);
		return name;
	}

	/**
	 * Return the name of the attribute in the specified mapping's target entity
	 * that is owned by the mapping.
	 */
	public static String getTargetAttributeName(RelationshipMapping relationshipMapping) {
		if (relationshipMapping == null) {
			return null;
		}
		Entity targetEntity = relationshipMapping.getResolvedTargetEntity();
		if (targetEntity == null) {
			return null;
		}
		for (ReadOnlyPersistentAttribute attribute : targetEntity.getPersistentType().getAllAttributes()) {
			if (attribute.getMapping().isOwnedBy(relationshipMapping)) {
				return attribute.getName();
			}
		}
		return null;
	}

	/**
	 * If appropriate, return the name of the single primary key column of the
	 * relationship target.
	 * Spec states:<br>
	 *     "The same name as the primary key column of the referenced table."<br>
	 * We are assuming that the primary key column is defined by the mappings instead of the database.
	 */
	public static String buildJoinColumnDefaultReferencedColumnName(ReadOnlyJoinColumn.Owner joinColumnOwner) {
		if (joinColumnOwner.getJoinColumnsSize() != 1) {
			return null;
		}
		Entity targetEntity = joinColumnOwner.getRelationshipTarget();
		if (targetEntity == null) {
			return null;
		}
		return targetEntity.getPrimaryKeyColumnName();
	}

	public static ColumnMapping getColumnMapping(String attributeName, PersistentType persistentType) {
		if ((attributeName == null) || (persistentType == null)) {
			return null;
		}
		for (ReadOnlyPersistentAttribute persAttribute : persistentType.getAllAttributes()) {
			if (attributeName.equals(persAttribute.getName())) {
				if (persAttribute.getMapping() instanceof ColumnMapping) {
					return (ColumnMapping) persAttribute.getMapping();
				}
				// keep looking or return null???
			}
		}
		return null;
	}

	public static RelationshipMapping getRelationshipMapping(String attributeName, TypeMapping typeMapping) {
		if ((attributeName == null) || (typeMapping == null)) {
			return null;
		}
		for (AttributeMapping attributeMapping : typeMapping.getAllAttributeMappings()) {
			if (attributeName.equals(attributeMapping.getName())) {
				if (attributeMapping instanceof RelationshipMapping) {
					return (RelationshipMapping) attributeMapping;
				}
				// keep looking or return null???
			}
		}
		return null;
	}

	public static void convertReferenceTableDefaultToSpecifiedJoinColumn(ReferenceTable referenceTable) {
		JoinColumn defaultJoinColumn = referenceTable.getDefaultJoinColumn();
		if (defaultJoinColumn != null) {
			String columnName = defaultJoinColumn.getDefaultName();
			String referencedColumnName = defaultJoinColumn.getDefaultReferencedColumnName();
			JoinColumn joinColumn = referenceTable.addSpecifiedJoinColumn();
			joinColumn.setSpecifiedName(columnName);
			joinColumn.setSpecifiedReferencedColumnName(referencedColumnName);
		}
	}

	public static void convertJoinTableDefaultToSpecifiedInverseJoinColumn(JoinTable joinTable) {
		JoinColumn defaultInverseJoinColumn = joinTable.getDefaultInverseJoinColumn();
		if (defaultInverseJoinColumn != null) {
			String columnName = defaultInverseJoinColumn.getDefaultName();
			String referencedColumnName = defaultInverseJoinColumn.getDefaultReferencedColumnName();
			JoinColumn joinColumn = joinTable.addSpecifiedInverseJoinColumn(0);
			joinColumn.setSpecifiedName(columnName);
			joinColumn.setSpecifiedReferencedColumnName(referencedColumnName);
		}
	}

	public static String getMetamodelFieldMapKeyTypeName(CollectionMapping2_0 mapping) {
		PersistentType targetType = mapping.getResolvedTargetType();
		String mapKey = mapping.getMapKey();
		if ((mapKey == null) || (targetType == null)) {
			String mapKeyClass = mapping.getFullyQualifiedMapKeyClass();
			return mapKeyClass != null ? mapKeyClass : MetamodelField.DEFAULT_TYPE_NAME;
		}
		ReadOnlyPersistentAttribute mapKeyAttribute = targetType.resolveAttribute(mapKey);
		if (mapKeyAttribute == null) {
			return MetamodelField.DEFAULT_TYPE_NAME;
		}
		AttributeMapping2_0 mapKeyMapping = (AttributeMapping2_0) mapKeyAttribute.getMapping();
		if (mapKeyMapping == null) {
			return MetamodelField.DEFAULT_TYPE_NAME;
		}
		return mapKeyMapping.getMetamodelTypeName();
	}

	// TODO move to TypeMapping? may need different name (or may need to rename existing #resolve...)
	public static Column resolveOverriddenColumn(TypeMapping overridableTypeMapping, String attributeName) {
		// convenience null check to simplify client code
		if (overridableTypeMapping == null) {
			return null;
		}

		for (TypeMapping typeMapping : overridableTypeMapping.getInheritanceHierarchy()) {
			Column column = typeMapping.resolveOverriddenColumn(attributeName);
			if (column != null) {
				return column;
			}
		}
		return null;
	}

	// TODO move to TypeMapping? may need different name (or may need to rename existing #resolve...)
	public static Relationship resolveOverriddenRelationship(TypeMapping overridableTypeMapping, String attributeName) {
		// convenience null check to simplify client code
		if (overridableTypeMapping == null) {
			return null;
		}

		for (TypeMapping typeMapping : overridableTypeMapping.getInheritanceHierarchy()) {
			Relationship relationship = typeMapping.resolveOverriddenRelationship(attributeName);
			if (relationship != null) {
				return relationship;
			}
		}
		return null;
	}

	public static String getPrimaryKeyColumnName(Entity entity) {
		String pkColumnName = null;
		for (ReadOnlyPersistentAttribute attribute : entity.getPersistentType().getAllAttributes()) {
			String current = attribute.getPrimaryKeyColumnName();
			if (current != null) {
				// 229423 - if the attribute is a primary key, but it has an attribute override,
				// use the override column instead
				ReadOnlyAttributeOverride attributeOverride = entity.getAttributeOverrideContainer().getOverrideNamed(attribute.getName());
				if (attributeOverride != null) {
					current = attributeOverride.getColumn().getName();
				}
			}
			if (pkColumnName == null) {
				pkColumnName = current;
			} else {
				if (current != null) {
					// if we encounter a composite primary key, return null
					return null;
				}
			}
		}
		// if we encounter only a single primary key column name, return it
		return pkColumnName;
	}

	/**
	 * "Unqualify" the specified attribute name, removing the mapping's name
	 * from the front of the attribute name if it is present. For example, if
	 * the mapping's name is <code>"foo"</code>, the attribute name
	 * <code>"foo.bar"</code> would be converted to <code>"bar"</code>).
	 * Return <code>null</code> if the attribute name cannot be "unqualified".
	 */
	public static String unqualify(String mappingName, String attributeName) {
		if (mappingName == null) {
			return null;
		}
		if ( ! attributeName.startsWith(mappingName)) {
			return null;
		}
		int mappingNameLength = mappingName.length();
		if (attributeName.length() <= mappingNameLength) {
			return null;
		}
		return (attributeName.charAt(mappingNameLength) == '.') ? attributeName.substring(mappingNameLength + 1) : null;
	}

	/**
	 * This transformer will prepend a specified qualifier, followed by a
	 * dot ('.'), to a string. For example, if a mapping's name is
	 * <code>"foo"</code> and one of its attribute's is named
	 * <code>"bar"</code>, the attribute's name will be transformed
	 * into <code>"foo.bar"</code>. If the specified qualifier is
	 * <code>null</code> (or an empty string), only a dot will be prepended
	 * to a string.
	 */
	public static class QualifierTransformer
		implements Transformer<String, String>
	{
		private final String prefix;
		public QualifierTransformer(String qualifier) {
			super();
			this.prefix = (qualifier == null) ? "." : qualifier + '.'; //$NON-NLS-1$
		}
		public String transform(String s) {
			return this.prefix + s;
		}
	}

	/**
	 * TODO temporary hack since we don't know yet where to put
	 * any messages for types in another project (e.g. referenced by
	 * persistence.xml)
	 */
	public static boolean nodeIsInternalSource(JavaJpaContextNode contextNode, JavaResourceNode resourceNode) {
		IResource resource = contextNode.getResource();
		// 'resource' will be null if the node is "external" and binary;
		// the resource will be in a different project if the node is "external" and source;
		// the node will be binary if it is in a JAR in the current project
		return (resource != null) &&
				resource.getProject().equals(contextNode.getJpaProject().getProject()) &&
				(resourceNode instanceof SourceNode);
	}


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

	/**
	 * Suppress default constructor, ensuring non-instantiability.
	 */
	private MappingTools() {
		super();
		throw new UnsupportedOperationException();
	}
}
