/*******************************************************************************
 * Copyright (c) 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.eclipselink.core.internal.context.orm;

import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jpt.common.core.internal.utility.JDTTools;
import org.eclipse.jpt.common.core.resource.java.JavaResourceAttribute;
import org.eclipse.jpt.common.core.resource.java.JavaResourceField;
import org.eclipse.jpt.common.core.resource.java.JavaResourceMethod;
import org.eclipse.jpt.common.core.utility.TextRange;
import org.eclipse.jpt.common.utility.internal.ClassName;
import org.eclipse.jpt.common.utility.internal.iterables.ArrayIterable;
import org.eclipse.jpt.jpa.core.JpaStructureNode;
import org.eclipse.jpt.jpa.core.context.AccessType;
import org.eclipse.jpt.jpa.core.context.CollectionMapping;
import org.eclipse.jpt.jpa.core.context.TypeMapping;
import org.eclipse.jpt.jpa.core.context.java.Accessor;
import org.eclipse.jpt.jpa.core.context.java.JavaAttributeMapping;
import org.eclipse.jpt.jpa.core.context.java.JavaPersistentAttribute;
import org.eclipse.jpt.jpa.core.context.orm.EntityMappings;
import org.eclipse.jpt.jpa.core.context.orm.OrmPersistentType;
import org.eclipse.jpt.jpa.core.internal.context.java.AbstractJavaJpaContextNode;
import org.eclipse.jpt.jpa.core.internal.jpa1.context.java.GenericJavaNullAttributeMapping;
import org.eclipse.jpt.jpa.core.jpa2.context.MetamodelField;
import org.eclipse.jpt.jpa.core.jpa2.context.java.JavaPersistentAttribute2_0;
import org.eclipse.jpt.jpa.core.jpa2.resource.java.JPA2_0;
import org.eclipse.jpt.jpa.eclipselink.core.JptJpaEclipseLinkCorePlugin;
import org.eclipse.jpt.jpa.eclipselink.core.context.java.JavaEclipseLinkPersistentAttribute;
import org.eclipse.jpt.jpa.eclipselink.core.resource.orm.XmlAttributeMapping;

public class VirtualJavaPersistentAttribute extends AbstractJavaJpaContextNode
	implements JavaPersistentAttribute2_0, JavaEclipseLinkPersistentAttribute
{
	private final XmlAttributeMapping xmlAttributeMapping;
	
	private final JavaAttributeMapping attributeMapping;

	public VirtualJavaPersistentAttribute(OrmPersistentType parent, XmlAttributeMapping xmlAttributeMapping) {
		super(parent);
		this.xmlAttributeMapping = xmlAttributeMapping;
		this.attributeMapping = new GenericJavaNullAttributeMapping(this);
	}

	public XmlAttributeMapping getXmlAttributeMapping() {
		return this.xmlAttributeMapping;
	}

	public JavaAttributeMapping getMapping() {
		return this.attributeMapping;
	}

	public JavaAttributeMapping setMappingKey(String key) {
		throw new UnsupportedOperationException("cannot set anything on a virtual java persistent attribute"); //$NON-NLS-1$
	}

	public Accessor getAccessor() {
		return null;
	}

	public JavaResourceAttribute getResourceAttribute() {
		return null;
	}

	public boolean isFor(JavaResourceField resourceField) {
		return false;
	}

	public boolean isFor(JavaResourceMethod resourceGetter, JavaResourceMethod resourceSetter) {
		return false;
	}

	public boolean contains(int offset, CompilationUnit astRoot) {
		throw new UnsupportedOperationException();
	}

	public String getTypeName() {
		String typeName = this.xmlAttributeMapping.getAttributeType();
		return typeName == null ? null : this.getEntityMappings().getFullyQualifiedName(typeName);
	}

	public boolean typeIsBasic() {
		return false;//not valid for a default basic mapping, specified in orm.xml
	}

	public String getSingleReferenceTargetTypeName() {
		return null; //used for building default target entity/embeddable, must be specified in a virtual mapping
	}

	public String getMultiReferenceTargetTypeName() {
		return null; //used for building default target entity/target class, must be specified in a virtual mapping
	}

	public String getMultiReferenceMapKeyTypeName() {
		return null; //used for building default map key class, must be specified in a virtual mapping
	}

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

	public String getMappingKey() {
		return null;
	}

	public String getDefaultMappingKey() {
		return null;
	}

	public boolean isVirtual() {
		throw new UnsupportedOperationException("Owing orm persistent attribute is specified, this should not be called."); //$NON-NLS-1$
	}

	public JavaPersistentAttribute getJavaPersistentAttribute() {
		return this;
	}


	// ********** JpaStructureNode implementation **********


	public JpaStructureNode getStructureNode(int textOffset) {
		throw new UnsupportedOperationException("There is no resource for a virtual java persistent attribute"); //$NON-NLS-1$
	}

	public TextRange getSelectionTextRange() {
		throw new UnsupportedOperationException("There is no resource for a virtual java persistent attribute"); //$NON-NLS-1$
	}

	public ContextType getContextType() {
		throw new UnsupportedOperationException("There is no resource for a virtual java persistent attribute"); //$NON-NLS-1$
	}

	public Class<? extends JpaStructureNode> getType() {
		throw new UnsupportedOperationException("There is no resource for a virtual java persistent attribute"); //$NON-NLS-1$
	}

	public void dispose() {
		throw new UnsupportedOperationException("There is no resource for a virtual java persistent attribute"); //$NON-NLS-1$
	}

	public AccessType getAccess() {
		return null;
	}

	public AccessType getSpecifiedAccess() {
		return null;
	}

	public void setSpecifiedAccess(AccessType newSpecifiedAccess) {
		throw new UnsupportedOperationException("cannot set anything on a virtual java persistent attribute"); //$NON-NLS-1$
	}

	public AccessType getDefaultAccess() {
		return null;
	}

	public TextRange getValidationTextRange(CompilationUnit astRoot) {
		throw new UnsupportedOperationException();
	}


	public boolean typeIsDateOrCalendar() {
		String typeName = this.getTypeName();
		if (typeName == null) {
			return false;
		}
		return JDTTools.typeIsSubType(this.getJavaProject(), typeName, DATE_TYPE_NAME)
			|| JDTTools.typeIsSubType(this.getJavaProject(), typeName, CALENDAR_TYPE_NAME);
	}

	public boolean typeIsSerializable() {
		String typeName = this.getTypeName();
		if (typeName == null) {
			return false;
		}
		return JDTTools.typeIsSubType(this.getJavaProject(), typeName, JDTTools.SERIALIZABLE_CLASS_NAME);
	}

	public boolean typeIsValidForVariableOneToOne() {
		String typeName = this.getTypeName();
		if (typeName == null) {
			return false;
		}
		IType type = JDTTools.findType(getJavaProject(), typeName);
		try {
			return type != null &&
					type.isInterface() &&
					this.interfaceIsValidForVariableOneToOne(typeName);
		}
		catch (JavaModelException e) {
			JptJpaEclipseLinkCorePlugin.log(e);
			return false;
		}
	}

	protected boolean interfaceIsValidForVariableOneToOne(String interfaceName) {
		return ! this.interfaceIsInvalidForVariableOneToOne(interfaceName);
	}

	// TODO we could probably add more interfaces to this list...
	protected boolean interfaceIsInvalidForVariableOneToOne(String interfaceName) {
		return (interfaceName == null) ||
				this.typeIsContainer(interfaceName) ||
				interfaceName.equals("org.eclipse.persistence.indirection.ValueHolderInterface"); //$NON-NLS-1$
	}

	/**
	 * return whether the specified type is one of the container
	 * types allowed by the JPA spec
	 */
	protected boolean typeIsContainer(String typeName) {
		return this.getJpaContainerDefinition(typeName).isContainer();
	}


	// ********** metamodel **********

	public String getMetamodelContainerFieldTypeName() {
		throw new UnsupportedOperationException("parent OrmPersistentAttribute implements this"); //$NON-NLS-1$
	}

	public String getMetamodelContainerFieldMapKeyTypeName() {
		throw new UnsupportedOperationException("parent OrmPersistentAttribute implements this"); //$NON-NLS-1$
	}


	public String getMetamodelTypeName() {
		String typeName = this.getTypeName();
		if (typeName == null) {
			return MetamodelField.DEFAULT_TYPE_NAME;
		}
		if (ClassName.isPrimitive(typeName)) {
			return ClassName.getWrapperClassName(typeName);  // ???
		}
		return typeName;
	}

	public JpaContainerDefinition getJpaContainerDefinition() {
		// 'typeName' may include array brackets ("[]")
		// but not generic type arguments (e.g. "<java.lang.String>")
		return this.getJpaContainerDefinition(this.getTypeName());
	}

	//I don't think we should be doing this here, I think OrmAttributeMappings should be responsible for their own JpaContainerDefinition
	//Generic can just get it from the JavaPersistentAttribute
	/**
	 * Return the JPA container definition corresponding to the specified type;
	 * return a "null" definition if the specified type is not "assignable to" one of the
	 * container types allowed by the JPA spec.
	 */
	protected JpaContainerDefinition getJpaContainerDefinition(String typeName) {
		if (typeName != null) {
			for (JpaContainerDefinition definition : getJpaContainerDefinitions()) {
				if (definition.isAssignableFrom(typeName)) {
					return definition;
				}
			}
		}
		return JpaContainerDefinition.Null.instance();
	}

	protected Iterable<JpaContainerDefinition> getJpaContainerDefinitions() {
		return JPA_CONTAINER_DEFINITIONS;
	}

	protected static final JpaContainerDefinition[] JPA_CONTAINER_DEFINITION_ARRAY = new JpaContainerDefinition[] {
		new CollectionJpaContainerDefinition(java.util.Set.class, JPA2_0.SET_ATTRIBUTE),
		new CollectionJpaContainerDefinition(java.util.List.class, JPA2_0.LIST_ATTRIBUTE),
		new CollectionJpaContainerDefinition(java.util.Collection.class, JPA2_0.COLLECTION_ATTRIBUTE),
		new MapJpaContainerDefinition(java.util.Map.class, JPA2_0.MAP_ATTRIBUTE)
	};

	protected static final Iterable<JpaContainerDefinition> JPA_CONTAINER_DEFINITIONS = new ArrayIterable<JpaContainerDefinition>(JPA_CONTAINER_DEFINITION_ARRAY);


	/**
	 * Abstract JPA container definition
	 */
	protected abstract static class AbstractJpaContainerDefinition
		implements JpaContainerDefinition
	{
		protected final Class<?> containerClass;
		protected final String metamodelContainerFieldTypeName;

		protected AbstractJpaContainerDefinition(Class<?> containerClass, String metamodelContainerFieldTypeName) {
			super();
			if ((containerClass == null) || (metamodelContainerFieldTypeName == null)) {
				throw new NullPointerException();
			}
			this.containerClass = containerClass;
			this.metamodelContainerFieldTypeName = metamodelContainerFieldTypeName;
		}

		public boolean isAssignableFrom(String typeName) {
			try {
				return this.containerClass.isAssignableFrom(Class.forName(typeName));
			}
			catch (ClassNotFoundException e) {
				return false;
			}
		}

		public boolean isContainer() {
			return true;
		}

		public String getMetamodelContainerFieldTypeName() {
			return this.metamodelContainerFieldTypeName;
		}

		public String getMultiReferenceTargetTypeName(JavaResourceAttribute resourceAttribute) {
			throw new UnsupportedOperationException();
		}

		public String getMultiReferenceMapKeyTypeName(JavaResourceAttribute resourceAttribute) {
			throw new UnsupportedOperationException();
		}
	}

	/**
	 * Collection JPA container definition
	 */
	protected static class CollectionJpaContainerDefinition
		extends AbstractJpaContainerDefinition
	{
		protected CollectionJpaContainerDefinition(Class<?> collectionClass, String staticMetamodelTypeDeclarationTypeName) {
			super(collectionClass, staticMetamodelTypeDeclarationTypeName);
		}

		public String getMetamodelContainerFieldMapKeyTypeName(CollectionMapping mapping) {
			return null;
		}

		public boolean isMap() {
			return false;
		}
	}

	/**
	 * Map JPA container definition
	 */
	protected static class MapJpaContainerDefinition
		extends AbstractJpaContainerDefinition
	{
		protected MapJpaContainerDefinition(Class<?> mapClass, String staticMetamodelTypeDeclarationTypeName) {
			super(mapClass, staticMetamodelTypeDeclarationTypeName);
		}

		public String getMetamodelContainerFieldMapKeyTypeName(CollectionMapping mapping) {
			return mapping.getMetamodelFieldMapKeyTypeName();
		}

		public boolean isMap() {
			return true;
		}
	}


	// ********** misc **********

	@Override
	public OrmPersistentType getParent() {
		return (OrmPersistentType) super.getParent();
	}

	public OrmPersistentType getOwningPersistentType() {
		return this.getParent();
	}

	public TypeMapping getOwningTypeMapping() {
		return this.getOwningPersistentType().getMapping();
	}

	protected EntityMappings getEntityMappings() {
		return (EntityMappings) getParent().getMappingFileRoot();
	}

	public String getPrimaryKeyColumnName() {
		throw new UnsupportedOperationException("Owing orm persistent attribute should handle, this should not be called."); //$NON-NLS-1$
	}

	@Override
	public void toString(StringBuilder sb) {
		sb.append(this.getName());
	}
}
