/*   Copyright 2004 The Apache Software Foundation
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package org.apache.xmlbeans.impl.xpathgen;

import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlCursor.TokenType;

import javax.xml.namespace.QName;
import javax.xml.namespace.NamespaceContext;

/**
 * Generates an XPath String that points to a given position in an XML document
 */
public class XPathGenerator
{
    /**
     * Generates an XPath pointing to the position in the document indicated by <code>node</code>.
     * <p>If the <code>context</code> parameter is null, the XPath is absolute, otherwise the
     * XPath will be relative to the position indicated by <code>context</code>.</p>
     * <p>Note: the cursor position for the <code>node</code> parameter is not preserved</p>
     * @param node the position in the document that the generated path will point to
     * @param context the context node; the generated path will be relative to it if not null and if
     * pointing to an element on the path from the document root to <code>node</code>
     * @param nsctx a namespace context that will be used to obtain prefixes; a (non-default)
     * namespace mapping must be available for all required namespace URIs
     * @return the generated path as a <code>String</code>
     * @throws XPathGenerationException if the path could not be generated: the cursor is in a bad
     * position (like over a comment) or no prefix mapping was found for one of the namespace URIs
     */
    public static String generateXPath(XmlCursor node, XmlCursor context, NamespaceContext nsctx)
        throws XPathGenerationException
    {
        if (node == null)
            throw new IllegalArgumentException("Null node");
        if (nsctx == null)
            throw new IllegalArgumentException("Null namespace context");
        TokenType tt = node.currentTokenType();
        if (context != null && node.isAtSamePositionAs(context))
            return ".";
        switch (tt.intValue())
        {
            case TokenType.INT_ATTR:
                QName name = node.getName();
                node.toParent();
                String pathToParent = generateInternal(node, context, nsctx);
                return pathToParent + '/' + '@' + qnameToString(name, nsctx);
            case TokenType.INT_NAMESPACE:
                name = node.getName();
                node.toParent();
                pathToParent = generateInternal(node, context, nsctx);
                String prefix = name.getLocalPart();
                if (prefix.length() == 0)
                    return pathToParent + "/@xmlns";
                else
                    return pathToParent + "/@xmlns:" + prefix;
            case TokenType.INT_START:
            case TokenType.INT_STARTDOC:
                return generateInternal(node, context, nsctx);
            case TokenType.INT_TEXT:
                int nrOfTextTokens = countTextTokens(node);
                node.toParent();
                pathToParent = generateInternal(node, context, nsctx);
                if (nrOfTextTokens == 0)
                    return pathToParent + "/text()";
                else
                    return pathToParent + "/text()[position()=" + nrOfTextTokens + ']';
            default:
                throw new XPathGenerationException("Cannot generate XPath for cursor position: " +
                    tt.toString());
        }
    }

    private static String generateInternal(XmlCursor node, XmlCursor context, NamespaceContext nsctx)
        throws XPathGenerationException
    {
        if (node.isStartdoc())
            return "";
        if (context != null && node.isAtSamePositionAs(context))
            return ".";
        assert node.isStart();
        QName name = node.getName();
        XmlCursor d = node.newCursor();
        if (!node.toParent())
            return "/" + name;
        int elemIndex = 0, i = 1;
        node.push();
        if (!node.toChild(name))
            throw new IllegalStateException("Must have at least one child with name: " + name);
        do
        {
            if (node.isAtSamePositionAs(d))
                elemIndex = i;
            else
                i++;
        } while (node.toNextSibling(name));
        node.pop();
        d.dispose();
        String pathToParent = generateInternal(node, context, nsctx);
        return  i == 1 ? pathToParent + '/' + qnameToString(name, nsctx) :
            pathToParent + '/' + qnameToString(name, nsctx) + '[' + elemIndex + ']';
    }

    private static String qnameToString(QName qname, NamespaceContext ctx)
        throws XPathGenerationException
    {
        String localName = qname.getLocalPart();
        String uri = qname.getNamespaceURI();
        if (uri.length() == 0)
            return localName;
        String prefix = qname.getPrefix();
        if (prefix != null && prefix.length() > 0)
        {
            // Try to use the same prefix if it maps to the right URI
            String mappedUri = ctx.getNamespaceURI(prefix);
            if (uri.equals(mappedUri))
                return prefix + ':' + localName;
        }
        // The prefix is not specified, or it is not mapped to the right URI
        prefix = ctx.getPrefix(uri);
        if (prefix == null)
            throw new XPathGenerationException("Could not obtain a prefix for URI: " + uri);
        if (prefix.length() == 0)
            throw new XPathGenerationException("Can not use default prefix in XPath for URI: " + uri);
        return prefix + ':' + localName;
    }

    /**
     * Computes how many text nodes the 
     * @param c the position in the document
     * @return how many text nodes occur before the position determined by <code>c</code>
     */
    private static int countTextTokens(XmlCursor c)
    {
        int k = 0;
        int l = 0;
        XmlCursor d = c.newCursor();
        c.push();
        c.toParent();
        TokenType tt = c.toFirstContentToken();
        while (!tt.isEnd())
        {
            if (tt.isText())
            {
                if (c.comparePosition(d) > 0)
                    // We have moved after the initial position
                    l++;
                else
                    k++;
            }
            else if (tt.isStart())
                c.toEndToken();
            tt = c.toNextToken();
        }
        c.pop();
        return l == 0 ? 0 : k;
    }

    public static void main(String[] args) throws org.apache.xmlbeans.XmlException
    {
        String xml =
            "<root>\n" +
                "<ns:a xmlns:ns=\"http://a.com\"><b foo=\"value\">text1<c/>text2<c/>text3<c>text</c>text4</b></ns:a>\n" +
                "</root>";
        NamespaceContext ns = new NamespaceContext() {
            public String getNamespaceURI(String prefix)
            {
                if ("ns".equals(prefix))
                    return "http://a.com";
                else
                    return null;
            }
            public String getPrefix(String namespaceUri)
            {
                return null;
            }
            public java.util.Iterator getPrefixes(String namespaceUri)
            {
                return null;
            }
        };
        XmlCursor c = org.apache.xmlbeans.XmlObject.Factory.parse(xml).newCursor();
        c.toFirstContentToken(); // on <root>
        c.toFirstContentToken(); // on <a>
        c.toFirstChild();        // on <b>
        c.toFirstChild();        // on <c>
        c.push(); System.out.println(generateXPath(c, null, ns)); c.pop();
        c.toNextSibling();
        c.toNextSibling();       // on the last <c>
        c.push(); System.out.println(generateXPath(c, null, ns)); c.pop();
        XmlCursor d = c.newCursor();
        d.toParent();
        c.push(); System.out.println(generateXPath(c, d, ns)); c.pop();
        d.toParent();
        c.push(); System.out.println(generateXPath(c, d, ns)); c.pop();
        c.toFirstContentToken(); // on text content of the last <c>
        c.push(); System.out.println(generateXPath(c, d, ns)); c.pop();
        c.toParent();
        c.toPrevToken();         // on text content before the last <c>
        c.push(); System.out.println(generateXPath(c, d, ns)); c.pop();
        c.toParent();            // on <b>
        c.push(); System.out.println(generateXPath(c, d, ns)); c.pop();
        c.toFirstAttribute();    // on the "foo" attribute
        c.push(); System.out.println(generateXPath(c, d, ns)); c.pop();
        c.toParent();
        c.toParent();
        c.toNextToken();         // on the "xmlns:ns" attribute
        c.push(); System.out.println(generateXPath(c, d, ns)); c.pop();
        c.push(); System.out.println(generateXPath(c, null, ns)); c.pop();
    }
}
