/*******************************************************************************
 * 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.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jpt.core.internal.IMappingKeys;
import org.eclipse.jpt.core.internal.IPersistentAttribute;
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(DefaultsContext defaultsContext) {
		return new DefaultsContextWrapper(defaultsContext) {
			public Object getDefault(String key) {
				return XmlTypeContext.this.getDefault(key, getWrappedDefaultsContext());
			}
			@Override
			public CompilationUnit astRoot() {
				//TODO need to somehow not build this astRoot every time.  can we store the JavaPersistentType we are finding?
				return javaPersistentType().getType().astRoot();
			}
		};
	}
	
	
	protected Object getDefault(String key, DefaultsContext defaultsContext) {
		return defaultsContext.getDefault(key);
	}	
	
	public XmlPersistentType getPersistentType() {
		return getXmlTypeMapping().getPersistentType();
	}
	
	public boolean isRefreshed() {
		return this.refreshed;
	}

	private void checkCanceled(IProgressMonitor monitor) {
		if (monitor.isCanceled()) {
			throw new OperationCanceledException();
		}		
	}

	@Override
	public void refreshDefaults(DefaultsContext parentDefaults, IProgressMonitor monitor) {
		super.refreshDefaults(parentDefaults, monitor);
		this.refreshed = true;
		if (this.javaTypeContext != null) {
			this.javaTypeContext.refreshDefaults(parentDefaults, monitor);
		}
		refreshPersistentType(parentDefaults, monitor);
		DefaultsContext wrappedDefaultsContext = wrapDefaultsContext(parentDefaults);
		refreshTableContext(wrappedDefaultsContext, monitor);
		this.xmlTypeMapping.refreshDefaults(wrappedDefaultsContext);
		
		refreshAttributeMappingContextDefaults(wrappedDefaultsContext, monitor);
	}
	
	protected void refreshTableContext(DefaultsContext defaultsContext, IProgressMonitor monitor) {
	}
	
	public void refreshAttributeMappingContextDefaults(DefaultsContext defaultsContext, IProgressMonitor monitor) {
		for (XmlAttributeContext context : this.attributeMappingContexts) {
			checkCanceled(monitor);
			context.refreshDefaults(context.wrapDefaultsContext(defaultsContext), monitor);
		}
		for (XmlAttributeContext context : this.virtualAttributeMappingContexts) {
			checkCanceled(monitor);
			context.refreshDefaults(context.wrapDefaultsContext(defaultsContext), monitor);
		}
	}
	
	protected void refreshPersistentType(DefaultsContext defaultsContext, IProgressMonitor monitor) {
		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) {
			checkCanceled(monitor);
			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()) {
			checkCanceled(monitor);
			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()) {
			checkCanceled(monitor);
			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())
			);
		}
	}
}