/*******************************************************************************
 *  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.xpath.java;

import java.util.List;
import java.util.Vector;
import org.eclipse.jpt.common.core.internal.utility.SimpleTextRange;
import org.eclipse.jpt.common.core.utility.TextRange;
import org.eclipse.jpt.common.utility.Filter;
import org.eclipse.jpt.common.utility.internal.ArrayTools;
import org.eclipse.jpt.common.utility.internal.CollectionTools;
import org.eclipse.jpt.common.utility.internal.StringTools;
import org.eclipse.jpt.common.utility.internal.iterables.CompositeIterable;
import org.eclipse.jpt.common.utility.internal.iterables.EmptyIterable;
import org.eclipse.jpt.common.utility.internal.iterables.FilteringIterable;
import org.eclipse.jpt.common.utility.internal.iterables.SingleElementIterable;
import org.eclipse.jpt.common.utility.internal.iterables.TransformationIterable;
import org.eclipse.jpt.jaxb.core.JaxbNode;
import org.eclipse.jpt.jaxb.core.context.JaxbPackage;
import org.eclipse.jpt.jaxb.core.context.JaxbPackageInfo;
import org.eclipse.jpt.jaxb.core.context.XmlNs;
import org.eclipse.jpt.jaxb.core.context.XmlSchema;
import org.eclipse.jpt.jaxb.core.xsd.XsdAttributeUse;
import org.eclipse.jpt.jaxb.core.xsd.XsdElementDeclaration;
import org.eclipse.jpt.jaxb.core.xsd.XsdTypeDefinition;
import org.eclipse.jpt.jaxb.eclipselink.core.internal.validation.ELJaxbValidationMessageBuilder;
import org.eclipse.jpt.jaxb.eclipselink.core.internal.validation.ELJaxbValidationMessages;
import org.eclipse.wst.validation.internal.provisional.core.IMessage;


public class XPath {
	
	public static String DELIM = "/";
	
	public static String ATT_PREFIX = "@";
	
	public static String TEXT = "text()";
	
	public static String SELF = ".";
	
	public static String COLON = ":";
	
	public static char OPEN_BRACKET = '[';
	
	public static char CLOSE_BRACKET = ']';
	
	
	List<Step> steps;
	
	
	XPath(String xpathString) {
		this.steps = new Vector<Step>();
		parse(xpathString);
	}
	
	
	protected int getIndex(Step step) {
		return this.steps.indexOf(step);
	}
	
	protected Step getFirstStep() {
		if (this.steps.size() > 0) {
			return this.steps.get(0);
		}
		return null;
	}
	
	protected Step getNextStep(Step step) {
		int nextIndex = getIndex(step) + 1;
		if (this.steps.size() > nextIndex) {
			return this.steps.get(nextIndex);
		}
		return null;
	}
	
	protected void parse(String xpath) {
		for (String segment : xpath.split(DELIM, -1)) {
			this.steps.add(createStep(segment));
		}
	}
	
	protected Step createStep(String stepValue) {
		if (TEXT.equals(stepValue)) {
			return new TextStep();
		}
		else if (SELF.equals(stepValue)) {
			return new SelfStep();
		}
		else if (stepValue.startsWith(ATT_PREFIX)) {
			return tryCreateAttributeStep(stepValue);
		}
		else {
			return tryCreateElementStep(stepValue);
		}
	}
	
	protected Step tryCreateAttributeStep(String stepValue) {
		// must start with "@" - already tested that
		try {
			String attributeStepValue = stepValue.substring(1);
			String[] stepParts = parseStepParts(attributeStepValue);
			return new AttributeStep(stepParts[0], stepParts[1], ArrayTools.subArray(stepParts, 2, stepParts.length));
		}
		catch (IllegalArgumentException ife) {
			return new InvalidStep(stepValue);
		}
	}
	
	protected Step tryCreateElementStep(String stepValue) {
		try {
			String[] stepParts = parseStepParts(stepValue);
			return new ElementStep(stepParts[0], stepParts[1], ArrayTools.subArray(stepParts, 2, stepParts.length));
		}
		catch (IllegalArgumentException ife) {
			return new InvalidStep(stepValue);
		}
	}
	
	protected String[] parseStepParts(String stepValue) {
		String[] predicate = new String[0];
		int predicateStart = stepValue.lastIndexOf(OPEN_BRACKET);
		while (predicateStart >= 0) {
			int predicateEnd = stepValue.lastIndexOf(CLOSE_BRACKET);
			if (predicateEnd <= predicateStart || predicateEnd != stepValue.length() - 1) {
				throw new IllegalArgumentException();
			}
			predicate = ArrayTools.add(predicate, 0, stepValue.substring(predicateStart +1, predicateEnd));
			stepValue = stepValue.substring(0, predicateStart);
			predicateStart = stepValue.lastIndexOf(OPEN_BRACKET);
		}
		
		String nsPrefix = null;
		int colon = stepValue.indexOf(COLON);
		if (colon > 0) {
			if (stepValue.indexOf(COLON, colon + 1) != -1) {
				throw new IllegalArgumentException();
			}
			nsPrefix = stepValue.substring(0, colon);
			stepValue = stepValue.substring(colon +1);
		}
		
		if (StringTools.stringIsEmpty(stepValue)
				|| stepValue.indexOf(COLON) >= 0 
				|| stepValue.indexOf(OPEN_BRACKET) >= 0 
				|| stepValue.indexOf(CLOSE_BRACKET) >= 0
				|| stepValue.indexOf(' ') >= 0) {
			throw new IllegalArgumentException();
		}
		
		String[] result = ArrayTools.add(new String[0], nsPrefix);
		result = ArrayTools.add(result, stepValue);
		result = ArrayTools.addAll(result, predicate);
		return result;
	}
	
	
	// ***** content assist *****
	
	public Iterable<String> getCompletionProposals(
			Context context, XsdTypeDefinition xsdType, int pos, Filter<String> filter) {
		
		return getFirstStep().getCompletionProposals(context, xsdType, StringTools.EMPTY_STRING, pos, filter);
	}
	
	
	// ***** validation *****
	
	public void validate(Context context, XsdTypeDefinition xsdType, List<IMessage> messages) {
		getFirstStep().validate(context, xsdType, messages);
	}
	
	protected TextRange buildTextRange(Context context, Step step) {
		TextRange entireTextRange = context.getTextRange();
		int start = 0;
		for (Step each : this.steps) {
			int length = each.getValue().length() + 2;  // include leading/trailing " or /
			if (each == step) {
				return new SimpleTextRange(entireTextRange.getOffset() + start, length, entireTextRange.getLineNumber());
			}
			else {
				start += length - 1; // only include leading " or /
			}
		}
		throw new IllegalArgumentException("Step must be in list of this XPath's steps.");
	}
	
	
	protected class AttributeStep
			extends NamedComponentStep {
		
		protected AttributeStep(String nsPrefix, String localName, String[] predicates) {
			super(nsPrefix, localName, predicates);
		}
		
		
		@Override
		protected String getValue() {
			return ATT_PREFIX + super.getValue();
		}
		
		@Override
		protected XsdTypeDefinition resolveNextType(Context context, XsdTypeDefinition previousType) {
			String namespace = resolveNamespace(context);
			if (namespace == null) {
				return null;
			}
			
			XsdAttributeUse xsdAttribute = previousType.getAttribute(namespace, this.localName);
			return (xsdAttribute == null) ? null : xsdAttribute.getAttributeDeclaration().getType();
		}
		
		@Override
		protected void validate(
				Context context, XsdTypeDefinition previousType, List<IMessage> messages) {
			
			if (getNextStep() != null) {
				messages.add(
						ELJaxbValidationMessageBuilder.buildMessage(
								IMessage.HIGH_SEVERITY,
								ELJaxbValidationMessages.XML_PATH__ATTRIBUTE_SEGMENT_MUST_BE_LAST_SEGMENT,
								context.getContextObject(),
								getTextRange(context)));
				return;
			}
			
			super.validate(context, previousType, messages);
		}
		
		@Override
		protected XsdTypeDefinition validateLocalName(
				Context context, XsdTypeDefinition previousType, String namespace, List<IMessage> messages) {
			
			XsdAttributeUse xsdAttribute= previousType.getAttribute(namespace, this.localName);
			if (xsdAttribute == null) {
				messages.add(
						ELJaxbValidationMessageBuilder.buildMessage(
								IMessage.HIGH_SEVERITY,
								ELJaxbValidationMessages.XML_PATH__UNRESOLVED_ATTRIBUTE,
								new String[] { namespace, this.localName },
								context.getContextObject(),
								getTextRange(context)));
				return null;
			}
			else {
				return xsdAttribute.getAttributeDeclaration().getType();
			}
		}
		
//		@Override
//		protected TextRange buildNamespacePrefixTextRange(CompilationUnit astRoot) {
//			// assume nsPrefix != null
//			TextRange stepTextRange = ELJavaXmlPath.this.buildTextRange(this, astRoot);
//			return new SimpleTextRange(stepTextRange.getOffset() + 1, this.nsPrefix.length(), stepTextRange.getLineNumber());
//		}
	}

	protected class ElementStep
			extends NamedComponentStep {
		
		protected ElementStep(String nsPrefix, String localName, String[] predicates) {
			super(nsPrefix, localName, predicates);
		}
		
		
		@Override
		protected XsdTypeDefinition
				resolveNextType(Context context, XsdTypeDefinition previousType) {
		
			String namespace = resolveNamespace(context);
			if (namespace == null) {
				return null;
			}
			
			XsdElementDeclaration xsdElement = previousType.getElement(namespace, this.localName);
			return (xsdElement == null) ? null : xsdElement.getType();
		}
		
		
		@Override
		protected XsdTypeDefinition validateLocalName(
				Context context, XsdTypeDefinition previousType, String namespace, List<IMessage> messages) {
			
			XsdElementDeclaration xsdElement = previousType.getElement(namespace, this.localName);
			if (xsdElement == null) {
				messages.add(
						ELJaxbValidationMessageBuilder.buildMessage(
								IMessage.HIGH_SEVERITY,
								ELJaxbValidationMessages.XML_PATH__UNRESOLVED_ELEMENT,
								new String[] { namespace, this.localName },
								context.getContextObject(),
								getTextRange(context)));
				return null;
			}
			else {
				return xsdElement.getType();
			}
		}
		
//		@Override
//		protected TextRange buildNamespacePrefixTextRange(CompilationUnit astRoot) {
//			// assume nsPrefix != null
//			TextRange stepTextRange = ELJavaXmlPath.this.buildTextRange(this, astRoot);
//			return new SimpleTextRange(stepTextRange.getOffset(), this.nsPrefix.length(), stepTextRange.getLineNumber());
//		}
	}

	protected class InvalidStep
			extends Step {
		
		protected String value;
		
		protected InvalidStep(String value) {
			super();
			this.value = value;
		}
		
		@Override
		protected String getValue() {
			return this.value;
		}
		
		@Override
		protected XsdTypeDefinition
				resolveNextType(Context context, XsdTypeDefinition previousType) {
			
			return null;
		}
		
		@Override
		protected void validate(
				Context context, XsdTypeDefinition previousType, List<IMessage> messages) {
			
			messages. add(ELJaxbValidationMessageBuilder.buildMessage(
							IMessage.HIGH_SEVERITY,
							ELJaxbValidationMessages.XML_PATH__INVALID_FORM_ILLEGAL_SEGMENT,
							new String[] { getValue() },
							context.getContextObject(),
							getTextRange(context)));
			return;
		}
	}

	protected abstract class NamedComponentStep
			extends Step {
		
		protected String nsPrefix;
		
		protected String localName;
		
		protected List<String> predicates;
		
		
		protected NamedComponentStep(String nsPrefix, String localName, String[] predicates) {
			super();
			this.nsPrefix = nsPrefix;
			this.localName = localName;
			this.predicates = new Vector<String>();
			CollectionTools.addAll(this.predicates, predicates);
		}
		
		@Override
		protected String getValue() {
			StringBuffer sb = new StringBuffer();
			if (this.nsPrefix != null) {
				sb.append(nsPrefix);
				sb.append(COLON);
			}
			sb.append(this.localName);
			for (String predicate : this.predicates) {
				sb.append(OPEN_BRACKET);
				sb.append(predicate);
				sb.append(CLOSE_BRACKET);
			}
			return sb.toString();
		}
		
		protected String resolveNamespace(Context context) {
			JaxbPackage pkg = context.getJaxbPackage();
			if (this.nsPrefix == null) {
				return pkg.getNamespace();
			}
			else {
				JaxbPackageInfo pkgInfo = pkg.getPackageInfo();
				return (pkgInfo == null) ? null : pkgInfo.getNamespaceForPrefix(this.nsPrefix);
			}
		}
		
		@Override
		protected void validate(
				Context context, XsdTypeDefinition previousType, List<IMessage> messages) {
			
			String namespace = resolveNamespace(context);
			
			if (namespace == null) {
				messages.add(
						ELJaxbValidationMessageBuilder.buildMessage(
								IMessage.HIGH_SEVERITY,
								ELJaxbValidationMessages.XML_PATH__INVALID_NS_PREFIX,
								new String[] { this.nsPrefix },
								context.getContextObject(),
								getTextRange(context)));
			}
			
			XsdTypeDefinition nextType = (previousType == null) ? null : validateLocalName(context, previousType, namespace, messages);
			if (nextType != null) {
				Step nextStep = getNextStep();
				if (nextStep != null) {
					nextStep.validate(context, nextType, messages);
				}
			}
		}
		
		protected abstract XsdTypeDefinition validateLocalName(
				Context context, XsdTypeDefinition previousType, String namespace, List<IMessage> messages);
		
//		protected abstract TextRange buildNamespacePrefixTextRange(CompilationUnit astRoot);
	}

	protected class SelfStep
			extends Step {
		
		protected SelfStep() {
			super();
		}
		
		
		@Override
		protected String getValue() {
			return SELF;
		}
		
		@Override
		protected XsdTypeDefinition
				resolveNextType(Context context, XsdTypeDefinition previousType) {
			
			return previousType;
		}
		
		@Override
		protected void validate(
				Context context, XsdTypeDefinition previousType, List<IMessage> messages) {
			
			if (getIndex() != 0) {
				messages.add(
						ELJaxbValidationMessageBuilder.buildMessage(
								IMessage.HIGH_SEVERITY,
								ELJaxbValidationMessages.XML_PATH__SELF_SEGMENT_MUST_BE_FIRST_SEGMENT,
								context.getContextObject(),
								getTextRange(context)));
				return;
			}
			
			if (getNextStep() != null) {
				getNextStep().validate(context, previousType, messages);
			}
		}
	}

	protected abstract class Step {
		
		protected int getIndex() {
			return XPath.this.getIndex(this);
		}
		
		protected Step getNextStep() {
			return XPath.this.getNextStep(this);
		}
		
		protected abstract String getValue();
		
		protected abstract XsdTypeDefinition resolveNextType(Context context, XsdTypeDefinition previousType);
		
		protected Iterable<String> getCompletionProposals(
				Context context, XsdTypeDefinition previousType, 
				final String prefix, int pos, Filter<String> filter) {
			
			if (getTextRange(context).includes(pos) || getNextStep() == null) {
				return StringTools.convertToJavaStringLiterals(
						new FilteringIterable<String>(
								new TransformationIterable<String, String>(
										new CompositeIterable<String>(
												new SingleElementIterable(TEXT),
												getAttributeProposals(context, previousType),
												getElementProposals(context, previousType))) {
									@Override
									protected String transform(String o) {
										return StringTools.concatenate(prefix, o);
									}
								},
								filter));
			}
			
			Step nextStep = getNextStep();
			XsdTypeDefinition nextType = resolveNextType(context, previousType);
			if (nextStep != null && nextType != null) {
				return nextStep.getCompletionProposals(context, nextType, prefix + getValue() + DELIM, pos, filter);
			}
			
			return new SingleElementIterable(TEXT);
		}
		
		protected Iterable<String> getAttributeProposals(Context context, final XsdTypeDefinition xsdType) {
			return new CompositeIterable<String>(
					new CompositeIterable<String>(
							new TransformationIterable<XmlNs, Iterable<String>>(getXmlNsInfos(context)) {
								@Override
								protected Iterable<String> transform(final XmlNs xmlns) {
									return new TransformationIterable<String, String>(xsdType.getAttributeNames(xmlns.getNamespaceURI())) {
										@Override
										protected String transform(String o) {
											return StringTools.concatenate(ATT_PREFIX, xmlns.getPrefix(), COLON, o);
										}
									};
								}
							}),
					new TransformationIterable<String, String>(xsdType.getAttributeNames(context.getJaxbPackage().getNamespace())) {
						@Override
						protected String transform(String o) {
							return StringTools.concatenate(ATT_PREFIX, o);
						}
					});
		}
		
		protected Iterable<String> getElementProposals(Context context, final XsdTypeDefinition xsdType) {
			return new CompositeIterable<String>(
					new CompositeIterable<String>(
							new TransformationIterable<XmlNs, Iterable<String>>(getXmlNsInfos(context)) {
								@Override
								protected Iterable<String> transform(final XmlNs xmlns) {
									return new TransformationIterable<String, String>(xsdType.getElementNames(xmlns.getNamespaceURI(), false)) {
										@Override
										protected String transform(String o) {
											return StringTools.concatenate(xmlns.getPrefix(), COLON, o);
										}
									};
								}
							}),
					xsdType.getElementNames(context.getJaxbPackage().getNamespace(), false));
		}
		
		protected Iterable<XmlNs> getXmlNsInfos(Context context) {
			JaxbPackageInfo pkgInfo = context.getJaxbPackage().getPackageInfo();
			XmlSchema xmlSchema = (pkgInfo == null) ? null : pkgInfo.getXmlSchema();
			return (xmlSchema == null) ? EmptyIterable.<XmlNs>instance() : xmlSchema.getXmlNsPrefixes();
		}
		
		protected void validate(Context context, XsdTypeDefinition previousType, List<IMessage> messages) {
			// no op
		}
		
		protected TextRange getTextRange(Context context) {
			return XPath.this.buildTextRange(context, this);
		}
	}

	protected class TextStep
			extends Step {
		
		protected TextStep() {
			super();
		}
		
		@Override
		protected String getValue() {
			return TEXT;
		}
		
		@Override
		protected XsdTypeDefinition
				resolveNextType(Context context, XsdTypeDefinition previousType) {
			
			return previousType;
		}
		
		@Override
		protected void validate(
				Context context, XsdTypeDefinition previousType, List<IMessage> messages) {
			
			if (getNextStep() != null) {
				messages.add(
						ELJaxbValidationMessageBuilder.buildMessage(
								IMessage.HIGH_SEVERITY,
								ELJaxbValidationMessages.XML_PATH__TEXT_SEGMENT_MUST_BE_LAST_SEGMENT,
								context.getContextObject(),
								getTextRange(context)));
			}
		}
	}
	
	
	public interface Context {
		
		JaxbNode getContextObject();
		
		JaxbPackage getJaxbPackage();
		
		TextRange getTextRange();
	}
}
