/*******************************************************************************
 *  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 = ']';
	
	
	public static String attributeXPath(String prefix, String localName) {
		if (prefix == null) {
			return StringTools.concatenate(ATT_PREFIX, localName);
		}
		return StringTools.concatenate(ATT_PREFIX, prefix, COLON, localName);
	}
	
	public static String elementXPath(String prefix, String localName) {
		if (prefix == null) {
			return localName;
		}
		return StringTools.concatenate(prefix, COLON, localName);
	}
	
	
	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.XPATH__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.XPATH__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.XPATH__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.XPATH__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 "";
			}
			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.XPATH__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.XPATH__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>(
												getTextProposals(context, previousType),
												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> getTextProposals(Context context, final XsdTypeDefinition xsdType) {
			return (xsdType.hasTextContent()) ? new SingleElementIterable(TEXT) : EmptyIterable.instance();						
		}
		
		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 XPath.attributeXPath(xmlns.getPrefix(), o);
										}
									};
								}
							}),
					new TransformationIterable<String, String>(xsdType.getAttributeNames("")) {
						@Override
						protected String transform(String o) {
							return XPath.attributeXPath(null, 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 XPath.elementXPath(xmlns.getPrefix(), o);
										}
									};
								}
							}),
					xsdType.getElementNames("", 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.XPATH__TEXT_SEGMENT_MUST_BE_LAST_SEGMENT,
								context.getContextObject(),
								getTextRange(context)));
			}
		}
	}
	
	
	public interface Context {
		
		JaxbNode getContextObject();
		
		JaxbPackage getJaxbPackage();
		
		TextRange getTextRange();
	}
}
