/*******************************************************************************
 *  Copyright (c) 2011  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.jaxb.core.internal.context.java;

import java.util.List;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jpt.common.core.internal.utility.JDTTools;
import org.eclipse.jpt.common.core.utility.TextRange;
import org.eclipse.jpt.common.utility.Filter;
import org.eclipse.jpt.common.utility.internal.CollectionTools;
import org.eclipse.jpt.common.utility.internal.StringTools;
import org.eclipse.jpt.common.utility.internal.iterables.EmptyIterable;
import org.eclipse.jpt.common.utility.internal.iterables.SingleElementIterable;
import org.eclipse.jpt.jaxb.core.context.JaxbAttributeMapping;
import org.eclipse.jpt.jaxb.core.context.JaxbClassMapping;
import org.eclipse.jpt.jaxb.core.context.JaxbPackage;
import org.eclipse.jpt.jaxb.core.context.JaxbPackageInfo;
import org.eclipse.jpt.jaxb.core.context.JaxbPersistentAttribute;
import org.eclipse.jpt.jaxb.core.context.JaxbQName;
import org.eclipse.jpt.jaxb.core.context.JaxbTypeMapping;
import org.eclipse.jpt.jaxb.core.context.XmlElement;
import org.eclipse.jpt.jaxb.core.context.XmlElementWrapper;
import org.eclipse.jpt.jaxb.core.context.XmlSchemaType;
import org.eclipse.jpt.jaxb.core.context.java.JavaContextNode;
import org.eclipse.jpt.jaxb.core.internal.validation.DefaultValidationMessages;
import org.eclipse.jpt.jaxb.core.internal.validation.JaxbValidationMessages;
import org.eclipse.jpt.jaxb.core.resource.java.QNameAnnotation;
import org.eclipse.jpt.jaxb.core.resource.java.XmlElementAnnotation;
import org.eclipse.jpt.jaxb.core.xsd.XsdElementDeclaration;
import org.eclipse.jpt.jaxb.core.xsd.XsdTypeDefinition;
import org.eclipse.jpt.jaxb.core.xsd.XsdUtil;
import org.eclipse.wst.validation.internal.provisional.core.IMessage;
import org.eclipse.wst.validation.internal.provisional.core.IReporter;


public class GenericJavaXmlElement
		extends AbstractJavaContextNode
		implements XmlElement {
	
	protected final Context context;
	
	protected final JaxbQName qName;
	
	protected Boolean specifiedNillable;
	
	protected boolean defaultNillable;
	
	protected Boolean specifiedRequired;
	
	protected String defaultValue;
	
	protected String specifiedType;
	
	protected String defaultType;
	
	
	public GenericJavaXmlElement(JavaContextNode parent, Context context) {
		super(parent);
		this.context = context;
		this.qName = buildQName();
		this.specifiedNillable = buildSpecifiedNillable();
		this.defaultNillable = buildDefaultNillable();
		this.specifiedRequired = buildSpecifiedRequired();
		this.defaultValue = buildDefaultValue();
		this.specifiedType = buildSpecifiedType();
		this.defaultType = buildDefaultType();
	}
	
	
	@Override
	public void synchronizeWithResourceModel() {
		super.synchronizeWithResourceModel();
		this.qName.synchronizeWithResourceModel();
		setSpecifiedNillable_(buildSpecifiedNillable());
		setDefaultNillable_(buildDefaultNillable());
		setSpecifiedRequired_(buildSpecifiedRequired());
		setDefaultValue_(buildDefaultValue());
		setSpecifiedType_(buildSpecifiedType());
		setDefaultType_(buildDefaultType());
	}
	
	@Override
	public void update() {
		super.update();
		this.qName.update();
	}
	
	@Override
	public JavaContextNode getParent() {
		return (JavaContextNode) super.getParent();
	}
	
	protected Context getContext() {
		return this.context;
	}
	
	protected JaxbAttributeMapping getAttributeMapping() {
		return getContext().getAttributeMapping();
	}
	
	protected JaxbPersistentAttribute getPersistentAttribute() {
		return getContext().getAttributeMapping().getPersistentAttribute();
	}
	
	protected JaxbClassMapping getJaxbClassMapping() {
		return getPersistentAttribute().getClassMapping();
	}
	
	protected JaxbPackage getJaxbPackage() {
		return getJaxbClassMapping().getJaxbType().getJaxbPackage();
	}
	
	public XmlElementAnnotation getAnnotation(boolean createIfNull) {
		return this.context.getAnnotation(createIfNull);
	}
	
	
	// ***** schema component ref *****
	
	public JaxbQName getQName() {
		return this.qName;
	}
	
	protected JaxbQName buildQName() {
		return new XmlElementQName(this);
	}
	
	
	// ***** XmlElement.nillable *****
	
	public boolean isNillable() {
		return (this.specifiedNillable == null) ? isDefaultNillable() : getSpecifiedNillable().booleanValue();
	}
	
	public Boolean getSpecifiedNillable() {
		return this.specifiedNillable;
	}
	
	public void setSpecifiedNillable(Boolean newSpecifiedNillable) {
		getAnnotation(true).setNillable(newSpecifiedNillable);
		setSpecifiedNillable_(newSpecifiedNillable);
	}
	
	protected void setSpecifiedNillable_(Boolean newSpecifiedNillable) {
		Boolean oldNillable = this.specifiedNillable;
		this.specifiedNillable = newSpecifiedNillable;
		firePropertyChanged(SPECIFIED_NILLABLE_PROPERTY, oldNillable, newSpecifiedNillable);
	}
	
	protected Boolean buildSpecifiedNillable() {
		XmlElementAnnotation annotation = getAnnotation(false);
		return (annotation == null) ? null : annotation.getNillable();
	}
	
	public boolean isDefaultNillable() {
		return this.defaultNillable;
	}
	
	protected void setDefaultNillable_(boolean newNillable) {
		boolean oldNillable = this.defaultNillable;
		this.defaultNillable = newNillable;
		firePropertyChanged(DEFAULT_NILLABLE_PROPERTY, oldNillable, newNillable);
	}
	
	protected boolean buildDefaultNillable() {
		XmlElementAnnotation annotation = getAnnotation(false);
		return (annotation == null) ? getPersistentAttribute().isJavaResourceAttributeCollectionType() : false;
	}
	
	
	// ***** XmlElement.required *****

	public boolean isRequired() {
		return (this.specifiedRequired == null) ? isDefaultRequired() : this.specifiedRequired.booleanValue();
	}
	
	public Boolean getSpecifiedRequired() {
		return this.specifiedRequired;
	}
	
	public void setSpecifiedRequired(Boolean newSpecifiedRequired) {
		getAnnotation(true).setRequired(newSpecifiedRequired);
		setSpecifiedRequired_(newSpecifiedRequired);
	}
	
	protected void setSpecifiedRequired_(Boolean newSpecifiedRequired) {
		Boolean oldRequired = this.specifiedRequired;
		this.specifiedRequired = newSpecifiedRequired;
		firePropertyChanged(SPECIFIED_REQUIRED_PROPERTY, oldRequired, newSpecifiedRequired);
	}
	
	protected Boolean buildSpecifiedRequired() {
		XmlElementAnnotation annotation = getAnnotation(false);
		return (annotation == null) ? null : annotation.getRequired();
	}
	
	public boolean isDefaultRequired() {
		return false;
	}
	
	
	// ***** XmlElement.defaultValue *****
	
	public String getDefaultValue() {
		return this.defaultValue;
	}
	
	public void setDefaultValue(String defaultValue) {
		getAnnotation(true).setDefaultValue(defaultValue);
		setDefaultValue_(defaultValue);
	}
	
	protected void setDefaultValue_(String defaultValue) {
		String oldDefaultValue = this.defaultValue;
		this.defaultValue = defaultValue;
		firePropertyChanged(DEFAULT_VALUE_PROPERTY, oldDefaultValue, defaultValue);		
	}
	
	protected String buildDefaultValue() {
		XmlElementAnnotation annotation = getAnnotation(false);
		return (annotation == null) ? null : annotation.getDefaultValue();
	}
	
	
	// ***** XmlElement.type *****
	
	public String getType() {
		return (this.specifiedType == null) ? getDefaultType() : this.specifiedType;
	}
	
	public String getSpecifiedType() {
		return this.specifiedType;
	}
	
	public void setSpecifiedType(String newSpecifiedType) {
		getAnnotation(true).setType(newSpecifiedType);
		setSpecifiedType_(newSpecifiedType);
	}
	
	protected void setSpecifiedType_(String newSpecifiedType) {
		String oldType = this.specifiedType;
		this.specifiedType = newSpecifiedType;
		firePropertyChanged(SPECIFIED_TYPE_PROPERTY, oldType, newSpecifiedType);
	}
	
	protected String buildSpecifiedType() {
		XmlElementAnnotation annotation = getAnnotation(false);
		return (annotation == null) ? null : annotation.getType();
	}
	
	public String getDefaultType() {
		return this.defaultType;
	}
	
	protected void setDefaultType_(String newType) {
		String oldType = this.defaultType;
		this.defaultType = newType;
		firePropertyChanged(DEFAULT_TYPE_PROPERTY, oldType, newType);
	}
	
	protected String buildDefaultType() {
		return this.context.getDefaultType();
	}
	
	public String getFullyQualifiedType() {
		return (this.specifiedType == null) ? getDefaultType() : getAnnotation(false).getFullyQualifiedTypeName();
	}
	
	
	// ***** misc *****
	
	public Iterable<String> getReferencedXmlTypeNames() {
		// only return the specified type - the default type should already be included
		return (this.specifiedType == null) ? 
				EmptyIterable.<String>instance() 
				: new SingleElementIterable(getFullyQualifiedType());
	}
	
	public XsdElementDeclaration getXsdElement() {
		XsdTypeDefinition xsdType = getJaxbClassMapping().getXsdTypeDefinition();
		return (xsdType == null) ? null : xsdType.getElement(this.qName.getNamespace(), this.qName.getName());
	}
	
	/**
	 * Return the expected schema type associated with the data type
	 */
	public XsdTypeDefinition getTypeXsdTypeDefinition() {
		String type = getFullyQualifiedType();
		if (StringTools.stringIsEmpty(type) || XmlElement.DEFAULT_TYPE_PROPERTY.equals(type)) {
			return null;
		}
		
		JaxbPackage pkg = getJaxbPackage();
		JaxbPackageInfo pkgInfo = (pkg == null) ? null : pkg.getPackageInfo();
		if (pkgInfo != null) {
			for (XmlSchemaType schemaType : pkgInfo.getXmlSchemaTypes()) {
				if (type.equals(schemaType.getFullyQualifiedType())) {
					return schemaType.getXsdTypeDefinition();
				}
			}
		}
		
		JaxbTypeMapping jaxbTypeMapping = getContextRoot().getTypeMapping(type);
		if (jaxbTypeMapping != null) {
			return jaxbTypeMapping.getXsdTypeDefinition();
		}
		
		String builtInType = getJaxbProject().getPlatform().getDefinition().getSchemaTypeMapping(type);
		if (builtInType != null) {
			return XsdUtil.getSchemaForSchema().getTypeDefinition(builtInType);
		}
		
		return null;
	}
	
	
	// ***** content assist *****
	
	@Override
	public Iterable<String> getJavaCompletionProposals(int pos, Filter<String> filter, CompilationUnit astRoot) {
		Iterable<String> result = super.getJavaCompletionProposals(pos, filter, astRoot);
		if (! CollectionTools.isEmpty(result)) {
			return result;
		}
		
		result = this.qName.getJavaCompletionProposals(pos, filter, astRoot);
		if (! CollectionTools.isEmpty(result)) {
			return result;
		}
		
		return EmptyIterable.instance();
	}
	
	
	// ***** validation *****
	
	@Override
	public TextRange getValidationTextRange(CompilationUnit astRoot) {
		XmlElementAnnotation annotation = getAnnotation(false);
		return (annotation == null) ? getParent().getValidationTextRange(astRoot) : annotation.getTextRange(astRoot);
	}
	
	public TextRange getTypeTextRange(CompilationUnit astRoot) {
		XmlElementAnnotation annotation = getAnnotation(false);
		return (annotation == null) ? getParent().getValidationTextRange(astRoot) : annotation.getTypeTextRange(astRoot);
	}
	
	@Override
	public void validate(List<IMessage> messages, IReporter reporter, CompilationUnit astRoot) {
		super.validate(messages, reporter, astRoot);
		validateQName(messages, reporter, astRoot);
		validateType(messages, reporter, astRoot);
		validateSchemaType(messages, reporter, astRoot);
	}
	
	protected void validateQName(List<IMessage> messages, IReporter reporter, CompilationUnit astRoot) {
		this.qName.validate(messages, reporter, astRoot);
	}
	
	protected void validateType(List<IMessage> messages, IReporter reporter, CompilationUnit astRoot) {
		String fqType = getFullyQualifiedType();
		if (StringTools.stringIsEmpty(fqType)) {
			messages.add(
					DefaultValidationMessages.buildMessage(
							IMessage.HIGH_SEVERITY,
							JaxbValidationMessages.XML_ELEMENT__UNSPECIFIED_TYPE,
							this,
							getTypeTextRange(astRoot)));
		}
		else if (! StringTools.stringIsEmpty(this.specifiedType)
				// verify that type actually exists before validating
				&& JDTTools.findType(getJaxbProject().getJavaProject(), fqType) != null) {
			String attributeBaseType = getAttributeMapping().getValueTypeName();
			if (! JDTTools.typeIsSubType(getJaxbProject().getJavaProject(), fqType, attributeBaseType)) {
				messages.add(
						DefaultValidationMessages.buildMessage(
								IMessage.HIGH_SEVERITY,
								JaxbValidationMessages.XML_ELEMENT__ILLEGAL_TYPE,
								new String[] { attributeBaseType },
								this,
								getTypeTextRange(astRoot)));
								
			}
		}
	}
	
	protected void validateSchemaType(List<IMessage> messages, IReporter reporter, CompilationUnit astRoot) {
		XsdElementDeclaration xsdElement = getXsdElement();
		if (xsdElement == null) {
			return;
		}
		
		XsdTypeDefinition expectedSchemaType = null;
		String typeName = this.context.getAttributeMapping().getDataTypeName();
		if (! XmlElement.DEFAULT_TYPE_PROPERTY.equals(getFullyQualifiedType())) {
			typeName = getFullyQualifiedType();
		}
		
		if (this.context.hasXmlID()) {
			expectedSchemaType = XsdUtil.getSchemaForSchema().getTypeDefinition("ID");
		}
		else if (this.context.hasXmlIDREF()) {
			expectedSchemaType = XsdUtil.getSchemaForSchema().getTypeDefinition("IDREF");
		}
		else if (this.context.hasXmlSchemaType()) {
			expectedSchemaType = this.context.getXmlSchemaType().getXsdTypeDefinition();
		}
		else if (! XmlElement.DEFAULT_TYPE_PROPERTY.equals(getFullyQualifiedType())) {
			expectedSchemaType = getTypeXsdTypeDefinition();
		}
		else {
			expectedSchemaType = this.context.getAttributeMapping().getDataTypeXsdTypeDefinition();
		}
		
		if (expectedSchemaType == null) {
			return;
		}
		
		if (! xsdElement.typeIsValid(expectedSchemaType, this.context.hasXmlList())) {
			messages.add(
					DefaultValidationMessages.buildMessage(
							IMessage.HIGH_SEVERITY,
							JaxbValidationMessages.XML_ELEMENT__INVALID_SCHEMA_TYPE,
							new String[] { typeName, xsdElement.getName() },
							this,
							this.qName.getNameTextRange(astRoot)));
		}
	}
	
	
	protected class XmlElementQName
			extends AbstractJavaElementQName {
		
		protected XmlElementQName(JavaContextNode parent) {
			super(parent, new QNameAnnotationProxy());
		}
		
		
		@Override
		protected JaxbPersistentAttribute getPersistentAttribute() {
			return GenericJavaXmlElement.this.getPersistentAttribute();
		}
		
		@Override
		protected XmlElementWrapper getElementWrapper() {
			return GenericJavaXmlElement.this.context.getElementWrapper();
		}	
	}
	
	
	protected class QNameAnnotationProxy 
			extends AbstractJavaQName.AbstractQNameAnnotationProxy {
		
		@Override
		protected QNameAnnotation getAnnotation(boolean createIfNull) {
			return GenericJavaXmlElement.this.getAnnotation(createIfNull);
		}
	}
	
	
	public interface Context {
		
		JaxbAttributeMapping getAttributeMapping();
		
		XmlElementAnnotation getAnnotation(boolean createIfNull);
		
		String getDefaultType();
		
		XmlElementWrapper getElementWrapper();
		
		boolean hasXmlID();
		
		boolean hasXmlIDREF();
		
		boolean hasXmlList();
		
		boolean hasXmlSchemaType();
		
		XmlSchemaType getXmlSchemaType();
	}
}
