/*******************************************************************************
 *  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.jaxb.eclipselink.core.internal.context.java;

import java.util.Iterator;
import java.util.List;
import javax.xml.namespace.QName;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jpt.common.core.resource.java.Annotation;
import org.eclipse.jpt.common.core.resource.java.NestableAnnotation;
import org.eclipse.jpt.common.core.utility.TextRange;
import org.eclipse.jpt.common.utility.Filter;
import org.eclipse.jpt.common.utility.internal.Bag;
import org.eclipse.jpt.common.utility.internal.CollectionTools;
import org.eclipse.jpt.common.utility.internal.iterables.EmptyIterable;
import org.eclipse.jpt.common.utility.internal.iterables.ListIterable;
import org.eclipse.jpt.common.utility.internal.iterables.SubListIterableWrapper;
import org.eclipse.jpt.common.utility.internal.iterables.SuperListIterableWrapper;
import org.eclipse.jpt.jaxb.core.context.JaxbAttributeMapping;
import org.eclipse.jpt.jaxb.core.context.JaxbPersistentAttribute;
import org.eclipse.jpt.jaxb.core.context.XmlElement;
import org.eclipse.jpt.jaxb.core.context.XmlElementWrapper;
import org.eclipse.jpt.jaxb.core.internal.context.java.GenericJavaXmlElementsMapping;
import org.eclipse.jpt.jaxb.core.resource.java.XmlElementAnnotation;
import org.eclipse.jpt.jaxb.core.resource.java.XmlElementWrapperAnnotation;
import org.eclipse.jpt.jaxb.eclipselink.core.context.java.ELXmlElementsMapping;
import org.eclipse.jpt.jaxb.eclipselink.core.context.java.ELXmlPath;
import org.eclipse.jpt.jaxb.eclipselink.core.internal.validation.ELJaxbValidationMessageBuilder;
import org.eclipse.jpt.jaxb.eclipselink.core.internal.validation.ELJaxbValidationMessages;
import org.eclipse.jpt.jaxb.eclipselink.core.resource.java.ELJaxb;
import org.eclipse.jpt.jaxb.eclipselink.core.resource.java.XmlPathAnnotation;
import org.eclipse.wst.validation.internal.provisional.core.IMessage;
import org.eclipse.wst.validation.internal.provisional.core.IReporter;


public class ELJavaXmlElementsMapping
		extends GenericJavaXmlElementsMapping
		implements ELXmlElementsMapping {
	
	protected final ContextListContainer<ELJavaXmlPath, XmlPathAnnotation> xmlPathContainer;
	
	
	public ELJavaXmlElementsMapping(JaxbPersistentAttribute parent) {
		super(parent);
		this.xmlPathContainer = buildXmlPathContainer();
	}
	
	
	// ***** sync/update *****
	
	@Override
	public void synchronizeWithResourceModel() {
		super.synchronizeWithResourceModel();
		this.xmlPathContainer.synchronizeWithResourceModel();
	}
	
	@Override
	public void update() {
		super.update();
		this.xmlPathContainer.update();
	}
	
	
	// ***** xmlPaths *****
	
	public ListIterable<ELXmlPath> getXmlPaths() {
		return new SuperListIterableWrapper<ELXmlPath>(this.xmlPathContainer.getContextElements());
	}
	
	public int getXmlPathsSize() {
		return this.xmlPathContainer.getContextElementsSize();
	}
	
	public ELXmlPath addXmlPath(int index) {
		XmlPathAnnotation annotation = (XmlPathAnnotation) getJavaResourceAttribute().addAnnotation(index, ELJaxb.XML_PATH);
		return this.xmlPathContainer.addContextElement(index, annotation);
	}
	
	public void removeXmlPath(int index) {
		getJavaResourceAttribute().removeAnnotation(index, ELJaxb.XML_PATH);
		this.xmlPathContainer.removeContextElement(index);
	}
	
	public void moveXmlPath(int targetIndex, int sourceIndex) {
		getJavaResourceAttribute().moveAnnotation(targetIndex, sourceIndex, ELJaxb.XML_PATH);
		this.xmlPathContainer.moveContextElement(targetIndex, sourceIndex);
	}
	
	protected ELJavaXmlPath buildXmlPath(XmlPathAnnotation xmlPathAnnotation) {
		return new ELJavaXmlPath(this, new XmlPathContext(xmlPathAnnotation));
	}
	
	protected ContextListContainer<ELJavaXmlPath, XmlPathAnnotation> buildXmlPathContainer() {
		XmlPathContainer container = new XmlPathContainer();
		container.initialize();
		return container;
	}
	
	protected ListIterable<XmlPathAnnotation> getXmlPathAnnotations() {
		return new SubListIterableWrapper<NestableAnnotation, XmlPathAnnotation>(
				getJavaResourceAttribute().getAnnotations(ELJaxb.XML_PATH));
	}
	
	
	// ***** misc *****
	
	@Override
	protected XmlElement buildXmlElement(XmlElementAnnotation xmlElementAnnotation) {
		return new ELJavaXmlElement(this, new XmlElementContext(xmlElementAnnotation));
	}
	
	@Override
	protected XmlElementWrapper buildXmlElementWrapper() {
		return new ELJavaXmlElementWrapper(this, new XmlElementWrapperContext());
	}
	
	
	// ***** 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;
		}
		
		for (ELJavaXmlPath xmlPath : this.xmlPathContainer.getContextElements()) {
			result = xmlPath.getJavaCompletionProposals(pos, filter, astRoot);
			if (! CollectionTools.isEmpty(result)) {
				return result;
			}
		}
		
		return EmptyIterable.instance();
	}
	
	
	// ***** validation *****
	
	@Override
	public void validate(List<IMessage> messages, IReporter reporter, CompilationUnit astRoot) {
		super.validate(messages, reporter, astRoot);
		
		if (getXmlPathsSize() > 0 ) {
			validateXmlPaths(messages, reporter, astRoot);
		}
	}
	
	protected void validateXmlPaths(List<IMessage> messages, IReporter reporter, CompilationUnit astRoot) {
		Iterator<XmlElement> xmlElements = getXmlElements().iterator();
		Iterator<ELJavaXmlPath> xmlPaths = this.xmlPathContainer.getContextElements().iterator();
		
		while (xmlElements.hasNext() && xmlPaths.hasNext()) {
			xmlElements.next();
			xmlPaths.next();
		}
		
		if (xmlElements.hasNext()) {
			messages.add(
					ELJaxbValidationMessageBuilder.buildMessage(
							IMessage.HIGH_SEVERITY,
							ELJaxbValidationMessages.XML_PATH__INSUFFICIENT_XML_PATHS_FOR_XML_ELEMENTS,
							this,
							getXmlPathsTextRange(astRoot)));
		}
		
		while (xmlPaths.hasNext()) {
			ELJavaXmlPath xmlPath = xmlPaths.next();
			messages.add(
					ELJaxbValidationMessageBuilder.buildMessage(
							IMessage.HIGH_SEVERITY,
							ELJaxbValidationMessages.XML_PATH__INSUFFICIENT_XML_ELEMENTS_FOR_XML_PATHS,
							this,
							xmlPath.getValidationTextRange(astRoot)));
		}
		
		for (ELJavaXmlPath xmlPath : this.xmlPathContainer.getContextElements()) {
			xmlPath.validate(messages, reporter, astRoot);
		}
	}
	
	@Override
	protected void validateDuplicateQName(XmlElement xmlElement, Bag<QName> xmlElementQNames, 
				List<IMessage> messages, CompilationUnit astRoot) {
		
		if (getXmlPathsSize() == 0) { 
			super.validateDuplicateQName(xmlElement, xmlElementQNames, messages, astRoot);
		}
	}
	
	protected TextRange getXmlPathsTextRange(CompilationUnit astRoot) {
		Annotation annotation = getJavaResourceAttribute().getAnnotation(ELJaxb.XML_PATHS);
		if (annotation == null) {
			annotation = getJavaResourceAttribute().getAnnotation(0, ELJaxb.XML_PATH);
		}
		return annotation.getTextRange(astRoot);
	}
	
	
	protected class XmlPathContainer
			extends ContextListContainer<ELJavaXmlPath, XmlPathAnnotation> {
		
		@Override
		protected String getContextElementsPropertyName() {
			return ELXmlElementsMapping.XML_PATHS_LIST;
		}
		
		@Override
		protected ELJavaXmlPath buildContextElement(XmlPathAnnotation resourceElement) {
			return ELJavaXmlElementsMapping.this.buildXmlPath(resourceElement);
		}
		
		@Override
		protected ListIterable<XmlPathAnnotation> getResourceElements() {
			return ELJavaXmlElementsMapping.this.getXmlPathAnnotations();
		}
		
		@Override
		protected XmlPathAnnotation getResourceElement(ELJavaXmlPath contextElement) {
			// in the context of this mapping, there will never be an ELXmlPath without an annotation
			return contextElement.getAnnotation();
		}
	}
	
	
	protected class XmlPathContext
			implements ELJavaXmlPath.Context {
		
		protected XmlPathAnnotation annotation;
		
		
		protected XmlPathContext(XmlPathAnnotation annotation) {
			this.annotation = annotation;
		}
		
		public XmlPathAnnotation getAnnotation() {
			return this.annotation;
		}
		
		public JaxbAttributeMapping getAttributeMapping() {
			return ELJavaXmlElementsMapping.this;
		}
	}
	
	
	protected class XmlElementContext
			extends GenericJavaXmlElementsMapping.XmlElementContext
			implements ELJavaXmlElement.Context {
		
		protected XmlElementContext(XmlElementAnnotation annotation) {
			super(annotation);
		}
		
		public boolean hasXmlPath() {
			return ELJavaXmlElementsMapping.this.getXmlPathsSize() > 0;
		}
	}
	
	protected class XmlElementWrapperContext
			implements ELJavaXmlElementWrapper.Context {
		
		public XmlElementWrapperAnnotation getAnnotation() {
			return ELJavaXmlElementsMapping.this.getXmlElementWrapperAnnotation();
		}
		
		public boolean hasXmlPath() {
			return ELJavaXmlElementsMapping.this.getXmlPathsSize() > 0;
		}
	}
}
