/*   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 tools.xml;

import org.apache.xmlbeans.impl.common.QNameHelper;
import org.apache.xmlbeans.impl.common.XmlWhitespace;
import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlException;

public class XmlComparator
{
    public static class Diagnostic
    {
        private StringBuilder message = null;

        private void add(String s)
        {
            if (message == null)
                 message = new StringBuilder();

            message.append(s).append("\n");
        }

        public boolean hasMessage()
        {
            return message != null;
        }

        public String toString()
        {
            return (message == null ? null : message.toString());
        }

        public static void add(Diagnostic diag, String s)
        {
            if ( diag!=null)
                diag.add(s);
        }
    }

    public static boolean wsCollapseEqual(String s1, String s2)
    {
        String s1c = XmlWhitespace.collapse(s1);
        String s2c = XmlWhitespace.collapse(s2);
        return (s1c.equals(s2c));
    }

    public static boolean compareNamesAndAttributes(XmlCursor cur1, XmlCursor cur2, Diagnostic diag)
    {
        if (!cur1.getName().equals(cur2.getName()))
        {
            Diagnostic.add(diag, "Element names " + QNameHelper.pretty(cur1.getName()) + " and " + QNameHelper.pretty(cur2.getName()) + " do not match");
            return false;
        }

        boolean more = cur1.toFirstAttribute();
        if (more)
        {
            for (; more; more = cur1.toNextAttribute())
            {
                String text1 = cur1.getTextValue();
                String text2 = cur2.getAttributeText(cur1.getName());
                if (text2 == null)
                {
                    Diagnostic.add(diag, "Attribute " + QNameHelper.pretty(cur1.getName()) + " not present");
                    return false;
                }

                if (!wsCollapseEqual(text1, text2))
                {
                    Diagnostic.add(diag, "Attribute values for " + QNameHelper.pretty(cur1.getName()) + " do not match");
                    return false;
                }
            }
            cur1.toParent();
        }

        more = cur2.toFirstAttribute();
        if (more)
        {
            for (; more; more = cur2.toNextAttribute())
            {
                String text1 = cur1.getAttributeText(cur2.getName());
                if (text1 == null)
                {
                    Diagnostic.add(diag, "Attribute " + QNameHelper.pretty(cur2.getName()) + " not present");
                    return false;
                }
            }
            cur2.toParent();
        }

        return true;
    }

    public static Diagnostic lenientlyCompareTwoXmlStrings(String actual, String expect)
        throws XmlException
    {
        Diagnostic diag = new Diagnostic();
        lenientlyCompareTwoXmlStrings(actual, expect, diag);
        return diag;
    }

    /**
     * Provides an utility to compare the xml inside the two strings
     * @return true if the xml inside the two strings is leniently the same
     *   otherwise false
     */
    public static boolean lenientlyCompareTwoXmlStrings(String actual, String expect, Diagnostic diag)
        throws XmlException
    {
        XmlObject xobj1 = XmlObject.Factory.parse(actual);
        XmlObject xobj2 = XmlObject.Factory.parse(expect);

        try (XmlCursor cur1 = xobj1.newCursor();
            XmlCursor cur2 = xobj2.newCursor()) {
            cur1.toFirstChild();
            cur2.toFirstChild();

            return lenientlyCompareTwoXmlStrings(cur1,  cur2, diag);
        }
    }

    /**
     * Provides an utility to compare the xml inside the two cursors
     * @return true if the xml inside the two strings is leniently the same
     *   otherwise false
     */
    public static boolean lenientlyCompareTwoXmlStrings(XmlCursor cur1, XmlCursor cur2, Diagnostic diag)
    {
        boolean match = true;
        int depth = 0;
        while (cur1.currentTokenType() != XmlCursor.TokenType.STARTDOC)
        {
            if (!compareNamesAndAttributes(cur1, cur2, diag))
            {
                match = false;
            }

            boolean hasChildren1 = cur1.toFirstChild();
            boolean hasChildren2 = cur2.toFirstChild();
            depth++;
            if (hasChildren1 != hasChildren2)
            {
                Diagnostic.add(diag, "Topology differs: one document has children where the other does not (" + QNameHelper.pretty(cur1.getName()) + ", " + QNameHelper.pretty(cur2.getName()) + ")"); // TODO: where?
                match = false;
                if (hasChildren1)
                {
                    cur1.toParent();
                    hasChildren1 = false;
                }
                if (hasChildren2)
                {
                    cur2.toParent();
                    hasChildren2 = false;
                }
            }
            else if (hasChildren1 == false)
            {
                if (!wsCollapseEqual(cur1.getTextValue(), cur2.getTextValue()))
                {
                    Diagnostic.add(diag, "Value " + cur1.getTextValue() + " differs from value " + cur2.getTextValue());
                    match = false;
                }
            }

            if (hasChildren1)
                continue;

            for (;;)
            {
                boolean hasSibling1 = cur1.toNextSibling();
                boolean hasSibling2 = cur2.toNextSibling();

                if (hasSibling1 != hasSibling2)
                {
                    Diagnostic.add(diag, "Topology differs: one document has siblings where the other does not"); // TODO: where?
                    hasSibling1 = false;
                    hasSibling2 = false;
                }

                if (hasSibling1)
                    break;

                cur1.toParent();
                cur2.toParent();
                depth--;

                if (cur1.currentTokenType() == XmlCursor.TokenType.STARTDOC || depth<=0)
                    break;
            }
        }
        return match;
    }
}
