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

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import org.eclipse.jpt.core.internal.IMappingKeys;
import org.eclipse.jpt.core.internal.IPersistentAttribute;
import org.eclipse.jpt.core.internal.IPersistentType;
import org.eclipse.jpt.core.internal.content.java.IJavaTypeMapping;
import org.eclipse.jpt.core.internal.content.java.JavaPersistentAttribute;
import org.eclipse.jpt.core.internal.content.java.JavaPersistentType;
import org.eclipse.jpt.core.internal.content.orm.OrmFactory;
import org.eclipse.jpt.core.internal.content.orm.XmlAttributeMapping;
import org.eclipse.jpt.core.internal.content.orm.XmlBasic;
import org.eclipse.jpt.core.internal.content.orm.XmlEmbedded;
import org.eclipse.jpt.core.internal.content.orm.XmlEmbeddedId;
import org.eclipse.jpt.core.internal.content.orm.XmlId;
import org.eclipse.jpt.core.internal.content.orm.XmlManyToMany;
import org.eclipse.jpt.core.internal.content.orm.XmlManyToOne;
import org.eclipse.jpt.core.internal.content.orm.XmlNullAttributeMapping;
import org.eclipse.jpt.core.internal.content.orm.XmlOneToMany;
import org.eclipse.jpt.core.internal.content.orm.XmlOneToOne;
import org.eclipse.jpt.core.internal.content.orm.XmlPersistentAttribute;
import org.eclipse.jpt.core.internal.content.orm.XmlPersistentType;
import org.eclipse.jpt.core.internal.content.orm.XmlTransient;
import org.eclipse.jpt.core.internal.content.orm.XmlTypeMapping;
import org.eclipse.jpt.core.internal.content.orm.XmlVersion;
import org.eclipse.jpt.core.internal.validation.IJpaValidationMessages;
import org.eclipse.jpt.core.internal.validation.JpaValidationMessages;
import org.eclipse.jpt.utility.internal.StringTools;
import org.eclipse.wst.validation.internal.provisional.core.IMessage;

public abstract class XmlTypeContext extends BaseContext
	implements TypeContext
{
	private XmlTypeMapping xmlTypeMapping;
	
	private JavaTypeContext javaTypeContext;
	
	private Collection<XmlAttributeContext> attributeMappingContexts;
	
	private Collection<XmlAttributeContext> virtualAttributeMappingContexts;
	
	private boolean refreshed;
	
	public XmlTypeContext(MappingFileContext parentContext, XmlTypeMapping xmlTypeMapping) {
		super(parentContext);
		this.xmlTypeMapping = xmlTypeMapping;
		this.attributeMappingContexts =  new ArrayList<XmlAttributeContext>();
		this.virtualAttributeMappingContexts =  new ArrayList<XmlAttributeContext>();
	}
	
	public void initialize() {
		JavaPersistentType javaPersistentType = javaPersistentType();
		PersistenceUnitContext puContext = getMappingFileContext().getPersistenceUnitContext();
		if (javaPersistentType != null) {
			if (puContext.containsDuplicateJavaPersistentType(javaPersistentType)) {
				return;
			}
			JavaTypeContext javaContext = 
				(JavaTypeContext) getPlatform().buildJavaTypeContext(this, javaPersistentType.getMapping());
			XmlTypeContext duplicate = puContext.xmlTypeMappingContextFor(javaPersistentType.getMapping());
			if (duplicate != null) {
				duplicate.setDuplicateJavaTypeMapping();
				puContext.addDuplicateJpaFile(javaContext);
				return;
			}
			this.javaTypeContext = javaContext;
		}
		
		initializeAttributeMappingContexts();
	}
	
	protected void initializeAttributeMappingContexts() {
		for (XmlAttributeMapping xmlAttributeMapping: this.xmlTypeMapping.getPersistentType().getSpecifiedAttributeMappings()) {
			this.attributeMappingContexts.add(buildContext(xmlAttributeMapping));
		}
	}
	
	protected XmlAttributeContext buildContext(XmlAttributeMapping attributeMapping) {
		String key = attributeMapping.getKey();
		if (key == IMappingKeys.ID_ATTRIBUTE_MAPPING_KEY) {
			return new XmlIdContext(this, (XmlId) attributeMapping);
		}
		else if (key == IMappingKeys.BASIC_ATTRIBUTE_MAPPING_KEY) {
			return new XmlBasicContext(this, (XmlBasic) attributeMapping);
		}
		else if (key == IMappingKeys.ONE_TO_MANY_ATTRIBUTE_MAPPING_KEY) {
			return new XmlOneToManyContext(this, (XmlOneToMany) attributeMapping);
		}
		else if (key == IMappingKeys.MANY_TO_ONE_ATTRIBUTE_MAPPING_KEY) {
			return new XmlManyToOneContext(this, (XmlManyToOne) attributeMapping);
		}
		else if (key == IMappingKeys.MANY_TO_MANY_ATTRIBUTE_MAPPING_KEY) {
			return new XmlManyToManyContext(this, (XmlManyToMany) attributeMapping);
		}
		else if (key == IMappingKeys.TRANSIENT_ATTRIBUTE_MAPPING_KEY) {
			return new XmlTransientContext(this, (XmlTransient) attributeMapping);
		}
		else if (key == IMappingKeys.EMBEDDED_ATTRIBUTE_MAPPING_KEY) {
			return new XmlEmbeddedContext(this, (XmlEmbedded) attributeMapping);
		}
		else if (key == IMappingKeys.EMBEDDED_ID_ATTRIBUTE_MAPPING_KEY) {
			return new XmlEmbeddedIdContext(this, (XmlEmbeddedId) attributeMapping);
		}
		else if (key == IMappingKeys.VERSION_ATTRIBUTE_MAPPING_KEY) {
			return new XmlVersionContext(this, (XmlVersion) attributeMapping);
		}
		else if (key == IMappingKeys.ONE_TO_ONE_ATTRIBUTE_MAPPING_KEY) {
			return new XmlOneToOneContext(this, (XmlOneToOne) attributeMapping);
		}
		else if (key == null) {
			return new XmlNullAttributeMappingContext(this, (XmlNullAttributeMapping) attributeMapping);
		}
		else {
			throw new IllegalArgumentException(attributeMapping.toString());
		}
	}
	
	protected void populateGeneratorRepository(GeneratorRepository generatorRepository) {
		//override as necessary
	}

	protected Collection<XmlAttributeContext> getXmlAttributeContexts() {
		return this.attributeMappingContexts;
	}
	
	protected MappingFileContext getMappingFileContext() {
		return (MappingFileContext) getParentContext();
	}
	
	protected XmlTypeMapping getXmlTypeMapping() {
		return this.xmlTypeMapping;
	}
	
	protected JavaTypeContext getJavaPersistentTypeContext() {
		return this.javaTypeContext;
	}
	
	protected IJavaTypeMapping getJavaTypeMapping() {
		if (this.javaTypeContext != null) {
			return this.javaTypeContext.getPersistentType().getMapping();
		}
		return null;
	}
	
	protected JavaPersistentType javaPersistentType() {
		return this.xmlTypeMapping.getPersistentType().findJavaPersistentType();
	}
	
	protected IJavaTypeMapping javaTypeMapping() {
		JavaPersistentType javaPersistentType = javaPersistentType();
		if (javaPersistentType != null) {
			return javaPersistentType.getMapping();
		}
		return null;
	}
	/**
	 * A java class is specified to be mapped in to orm.xml files in the same persistence unit.
	 * Null out the javaTypeMapping for this case, so that the context is no longer a particular
	 * orm.xml file.
	 */
	public void setDuplicateJavaTypeMapping() {
		this.javaTypeContext = null;
	}
	
	public DefaultsContext wrapDefaultsContext(final DefaultsContext defaultsContext) {
		return new DefaultsContext() {
			public Object getDefault(String key) {
				return XmlTypeContext.this.getDefault(key, defaultsContext);
			}
			
			public IPersistentType persistentType(String fullyQualifiedTypeName) {
				return defaultsContext.persistentType(fullyQualifiedTypeName);
			}
		};
	}
	
	
	protected Object getDefault(String key, DefaultsContext defaultsContext) {
		return defaultsContext.getDefault(key);
	}	
	
	public XmlPersistentType getPersistentType() {
		return getXmlTypeMapping().getPersistentType();
	}
	
	public boolean isRefreshed() {
		return this.refreshed;
	}

	public void refreshDefaults(DefaultsContext parentDefaults) {
		super.refreshDefaults(parentDefaults);
		this.refreshed = true;
		if (this.javaTypeContext != null) {
			this.javaTypeContext.refreshDefaults(parentDefaults);
		}
		refreshPersistentType(parentDefaults);
		DefaultsContext wrappedDefaultsContext = wrapDefaultsContext(parentDefaults);
		refreshTableContext(wrappedDefaultsContext);
		this.xmlTypeMapping.refreshDefaults(wrappedDefaultsContext);
		
		refreshAttributeMappingContextDefaults(wrappedDefaultsContext);
	}
	
	protected void refreshTableContext(DefaultsContext defaultsContext) {
	}
	
	public void refreshAttributeMappingContextDefaults(DefaultsContext defaultsContext) {
		for (XmlAttributeContext context : this.attributeMappingContexts) {
			context.refreshDefaults(context.wrapDefaultsContext(defaultsContext));
		}
		for (XmlAttributeContext context : this.virtualAttributeMappingContexts) {
			context.refreshDefaults(context.wrapDefaultsContext(defaultsContext));
		}
	}
	
	protected void refreshPersistentType(DefaultsContext defaultsContext) {
		XmlPersistentType xmlPersistentType = this.getXmlTypeMapping().getPersistentType();
		xmlPersistentType.refreshDefaults(defaultsContext);
		//get the java attribute names
		//check the specified xml attributes (those with an element in the xml), add
		//a xmlAttribute mapping for any java attribute name with default = true
		//if we already have an xml attribute mapping, then do nothing, 
		//the defaults refresh will get forwarded on the attribute mappings later.
		Collection<IPersistentAttribute> javaAttributes = javaAttributes();
		Collection<String> javaAttributeNames = new ArrayList<String>();
		for (IPersistentAttribute javaAttribute : javaAttributes) {
			String javaAttributeName = javaAttribute.getName();
			javaAttributeNames.add(javaAttributeName);
			XmlPersistentAttribute xmlAttribute = xmlPersistentType.attributeNamed(javaAttributeName);
			if (xmlAttribute == null) {
				createAndAddXmlAttributeFrom(javaAttribute, xmlPersistentType);
			}
			else {
				if (xmlAttribute.isVirtual()) {
					if (xmlAttribute.typeMapping().isXmlMetadataComplete()) {
						xmlAttribute.setSpecifiedMappingKey(javaAttribute.defaultMappingKey());
					}
					else {
						xmlAttribute.setSpecifiedMappingKey(javaAttribute.mappingKey());	
					}
				}
			}
		}
		
		Collection<String> specifiedXmlAttributeNames = new ArrayList<String>();
		for (XmlPersistentAttribute specifiedAttribute : xmlPersistentType.getSpecifiedPersistentAttributes()) {
			String attributeName = specifiedAttribute.getName();
			if (! StringTools.stringIsEmpty(attributeName)) {
				specifiedXmlAttributeNames.add(attributeName);
			}
		}
		
		// remove virtual attribute if there's no java representation 
		// *or* if it is mapped specifically
		Collection<XmlAttributeMapping> mappingsToRemove = new ArrayList<XmlAttributeMapping>();
		for (XmlAttributeMapping mapping : xmlPersistentType.getVirtualAttributeMappings()) {
			String attributeName = mapping.getPersistentAttribute().getName();
			if (! javaAttributeNames.contains(attributeName)
					|| specifiedXmlAttributeNames.contains(attributeName)) {
				mappingsToRemove.add(mapping);
			}
		}
		
		for (XmlAttributeMapping xmlAttributeMapping : mappingsToRemove) {
			xmlPersistentType.getVirtualAttributeMappings().remove(xmlAttributeMapping);
		}
		
		for (XmlAttributeMapping xmlAttributeMapping : this.xmlTypeMapping.getPersistentType().getVirtualAttributeMappings()) {
			this.virtualAttributeMappingContexts.add(buildContext(xmlAttributeMapping));
		}
	}
	
	private void createAndAddXmlAttributeFrom(IPersistentAttribute javaAttribute, XmlPersistentType persistentType) {
		//TODO also need to check xml mapping meta data complete flags and 
		//probably move all of this code to the context classes
		XmlAttributeMapping xmlAttributeMapping = null;
		String mappingKey;
		if (persistentType.getMapping().isXmlMetadataComplete()) {
			mappingKey = javaAttribute.defaultMappingKey();
		}
		else {
			mappingKey = javaAttribute.getMapping().getKey();
		}
		if (mappingKey == IMappingKeys.BASIC_ATTRIBUTE_MAPPING_KEY) {
			xmlAttributeMapping = OrmFactory.eINSTANCE.createXmlBasic();
		}
		else if (mappingKey == IMappingKeys.ID_ATTRIBUTE_MAPPING_KEY) {
			xmlAttributeMapping = OrmFactory.eINSTANCE.createXmlId();
		}
		else if (mappingKey == IMappingKeys.MANY_TO_MANY_ATTRIBUTE_MAPPING_KEY) {
			xmlAttributeMapping = OrmFactory.eINSTANCE.createXmlManyToMany();
		}
		else if (mappingKey == IMappingKeys.MANY_TO_ONE_ATTRIBUTE_MAPPING_KEY) {
			xmlAttributeMapping = OrmFactory.eINSTANCE.createXmlManyToOne();
		}
		else if (mappingKey == IMappingKeys.ONE_TO_MANY_ATTRIBUTE_MAPPING_KEY) {
			xmlAttributeMapping = OrmFactory.eINSTANCE.createXmlOneToMany();
		}
		else if (mappingKey == IMappingKeys.TRANSIENT_ATTRIBUTE_MAPPING_KEY) {
			xmlAttributeMapping = OrmFactory.eINSTANCE.createXmlTransient();
		}
		else if (mappingKey == IMappingKeys.EMBEDDED_ATTRIBUTE_MAPPING_KEY) {
			xmlAttributeMapping = OrmFactory.eINSTANCE.createXmlEmbedded();
		}
		else if (mappingKey == IMappingKeys.EMBEDDED_ID_ATTRIBUTE_MAPPING_KEY) {
			xmlAttributeMapping = OrmFactory.eINSTANCE.createXmlEmbeddedId();
		}
		else if (mappingKey == IMappingKeys.VERSION_ATTRIBUTE_MAPPING_KEY) {
			xmlAttributeMapping = OrmFactory.eINSTANCE.createXmlVersion();
		}
		else if (mappingKey == IMappingKeys.ONE_TO_ONE_ATTRIBUTE_MAPPING_KEY) {
			xmlAttributeMapping = OrmFactory.eINSTANCE.createXmlOneToOne();
		}
		else if (mappingKey == null) {
			xmlAttributeMapping = OrmFactory.eINSTANCE.createXmlNullAttributeMapping();
		}
		//TODO this isn't the way to do it, should update all the settings on the default mapping
		// during the refresh defaults of attribute mappings
		//xmlAttributeMapping.initializeFromAttributeMapping(javaAttribute.getMapping());
		persistentType.getVirtualAttributeMappings().add(xmlAttributeMapping);
		xmlAttributeMapping.getPersistentAttribute().setName(javaAttribute.getName());
	}
	
	protected Collection<IPersistentAttribute> javaAttributes() {
		Collection<IPersistentAttribute> javaAttributes = new ArrayList<IPersistentAttribute>();
		JavaPersistentType javaPersistentType = javaPersistentType();
		if (javaPersistentType != null) {
			for (Iterator<JavaPersistentAttribute> i = javaPersistentType.attributes(); i.hasNext(); ) {
				JavaPersistentAttribute persistentAttribute = i.next();
				javaAttributes.add(persistentAttribute);
			}
		}
		return javaAttributes;
	}
	
	@Override
	public void addToMessages(List<IMessage> messages) {
		super.addToMessages(messages);
		addClassMessages(messages);
		
		for (XmlAttributeContext context : this.attributeMappingContexts) {
			context.addToMessages(messages);
		}
		for (XmlAttributeContext context : this.virtualAttributeMappingContexts) {
			context.addToMessages(messages);
		}
	}
	
	protected void addClassMessages(List<IMessage> messages) {
		addUnspecifiedClassMessage(messages);
		addUnresolvedClassMessage(messages);
	}
	
	protected void addUnspecifiedClassMessage(List<IMessage> messages) {
		XmlPersistentType persistentType = xmlTypeMapping.getPersistentType();
		if (StringTools.stringIsEmpty(persistentType.getClass_())) {
			messages.add(
				JpaValidationMessages.buildMessage(
					IMessage.HIGH_SEVERITY,
					IJpaValidationMessages.PERSISTENT_TYPE_UNSPECIFIED_CLASS,
					persistentType, persistentType.classTextRange())
			);
		}
	}
	
	protected void addUnresolvedClassMessage(List<IMessage> messages) {
		XmlPersistentType persistentType = xmlTypeMapping.getPersistentType();
		if (! StringTools.stringIsEmpty(persistentType.getClass_())
				&& persistentType.findJdtType() == null) {
			messages.add(
				JpaValidationMessages.buildMessage(
					IMessage.HIGH_SEVERITY,
					IJpaValidationMessages.PERSISTENT_TYPE_UNRESOLVED_CLASS,
					new String[] {persistentType.getClass_()},
					persistentType, persistentType.classTextRange())
			);
		}
	}
}