/*   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 xmlobject.checkin;

import org.apache.xml.test.selectChldAtt.DocDocument;
import org.apache.xml.test.selectChldAtt.TypeExtendedC;
import org.apache.xmlbeans.*;
import org.junit.Test;

import javax.xml.namespace.QName;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

import static org.junit.Assert.assertTrue;

public class SelectChldAttTests {
    private static final String XSI_URI = "http://www.w3.org/2001/XMLSchema-instance";

    @Test
    public void testSelect() throws XmlException {
        String uri = "http://xml.apache.org/test/selectChldAtt";

        String xml = "<doc xmlns='" + uri + "'>\n" +
            "  <int>7</int>\n" +
            "  <string> ... some text ... </string>\n" +

            "  <elemA price='4.321'>\n" +
            "    <topLevelElement> this is wildcard bucket </topLevelElement>\n" +
            "  </elemA>\n" +

            "  <elemB xmlns:p='uri:other_namespace' \n" +
            "       p:att='attribute in #other namespace'>\n" +
            "    <someElement>2</someElement>\n" +
            "    <p:otherElement> element in #other namespace </p:otherElement>\n" +
            "  </elemB>\n" +

            "  <elemC xmlns:xsi='" + XSI_URI + "' \n" +
            "         xmlns:p='uri_other_namespace' \n" +
            "         xsi:type='typeExtendedC' \n" +
            "         att1='attribute from typeC' \n" +
            "         aditionalAtt='attribute added in type extension' \n" +
            "         p:validAtt='attribute in any bucket' >\n" +
            "    <someElement> element from typeC </someElement>\n" +
            "    <p:validElement> element in the 'any' bucket for typeExtendedC </p:validElement>\n" +
            "    <aditionalElement> element from typeExtendedC </aditionalElement>\n" +
            "  </elemC>\n" +
            "</doc>";

        DocDocument document = DocDocument.Factory.parse(xml);
        DocDocument.Doc doc = document.getDoc();
        Collection errors = new ArrayList();
        assertTrue("Valid instance", doc.validate(new XmlOptions().setErrorListener(errors)));
        printErrors(errors);

        XmlObject xo;
        XmlObject[] xos;

        // select a known element
        xos = doc.selectChildren(new QName(uri, "int"));
        //print("1 selectChildren 'int' : ", xos);
        assertTrue("1 selectChildren 'int' : ", verifyResult(xos, new String[]{"<xml-fragment>7</xml-fragment>"}));

        xos = doc.selectChildren(uri, "string");
        //print("2 selectChildren 'string' : ", xos);
        assertTrue("2 selectChildren 'string' : ", verifyResult(xos, new String[]{"<xml-fragment> ... some text ... </xml-fragment>"}));

        // elemA
        xos = doc.selectChildren(new QName(uri, "elemA"));
        //print("3 selectChildren 'elemA' : ", xos);
        assertTrue("3 selectChildren 'elemA' : ",
            verifyResult(xos, new String[]{"<xml-fragment price=\"4.321\" xmlns:sel=\"" + uri + "\">\n" +
                "  <sel:topLevelElement> this is wildcard bucket </sel:topLevelElement>\n" +
                "</xml-fragment>"}));

        // select a known attribute
        xo = xos[0].selectAttribute(new QName("", "price"));
        //print("4     selectAttribute 'price' : ", xo);
        assertTrue("4     selectAttribute 'price' : ",
            verifyResult(xo, "<xml-fragment>4.321</xml-fragment>"));

        // select all attributes
        QNameSet qns = QNameSet.forWildcardNamespaceString("##any", uri);
        xos = xos[0].selectAttributes(qns);
        //print("5     selectAttributes set'##any' :", xos);
        assertTrue("5     selectAttributes set'##any' :",
            verifyResult(xos, new String[]{"<xml-fragment>4.321</xml-fragment>"}));

        // elemB
        xos = doc.selectChildren(new QName(uri, "elemB"));
        //print("6 selectChildren 'elemB' : ", xos);

        //print("7     selectChildren set'##other' : " , xos[0].selectChildren(QNameSet.forWildcardNamespaceString("##other", uri)));
        assertTrue("7     selectChildren set'##other' : ",
            verifyResult(xos[0].selectChildren(QNameSet.forWildcardNamespaceString("##other", uri))
                , new String[]{"<xml-fragment xmlns:p=\"uri:other_namespace\"> element in #other namespace </xml-fragment>"}));
        //print("8     selectAttributes set'##other' : ", xos[0].selectAttributes(QNameSet.forWildcardNamespaceString("##other", uri)));
        assertTrue("8     selectAttributes set'##other' : ",
            verifyResult(xos[0].selectAttributes(QNameSet.forWildcardNamespaceString("##other", uri)),
                new String[]{"<xml-fragment xmlns:p=\"uri:other_namespace\">attribute in #other namespace</xml-fragment>"}));

        // elemC
        xos = doc.selectChildren(new QName(uri, "elemC"));
        //print("9 selectChildren 'elemC' : ", xos);
        //print("10    selectChildren set'##any' : " , xos[0].selectChildren(QNameSet.forWildcardNamespaceString("##any", uri)));
        assertTrue("10    selectChildren set'##any' : ",
            verifyResult(xos[0].selectChildren(QNameSet.forWildcardNamespaceString("##any", uri))
                , new String[]{"<xml-fragment xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:p=\"uri_other_namespace\"> element from typeC </xml-fragment>",
                    "<xml-fragment xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:p=\"uri_other_namespace\"> element in the 'any' bucket for typeExtendedC </xml-fragment>",
                    "<xml-fragment xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:p=\"uri_other_namespace\"> element from typeExtendedC </xml-fragment>"}));

        // select elements in the any bucket by excluding the the known elements
        QNameSetBuilder qnsb = new QNameSetBuilder();
        qnsb.add(new QName(uri, "someElement"));
        qnsb.add(new QName(uri, "aditionalElement"));
        qnsb.invert();

        //print("11a    selectChildren in the any bucket for typeExtendedC: " , xos[0].selectChildren(qnsb.toQNameSet()));
        assertTrue("11a    selectChildren in the any bucket for typeExtendedC: ",
            verifyResult(xos[0].selectChildren(qnsb.toQNameSet()),
                new String[]{"<xml-fragment xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:p=\"uri_other_namespace\"> element in the 'any' bucket for typeExtendedC </xml-fragment>"}));

        //print("11b    selectChildren in the any bucket for typeExtendedC: " , xos[0].selectChildren(TypeExtendedC.type.qnameSetForWildcardElements()));
        assertTrue("11b    selectChildren in the any bucket for typeExtendedC: ",
            verifyResult(xos[0].selectChildren(TypeExtendedC.type.qnameSetForWildcardElements()),
                new String[]{"<xml-fragment xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:p=\"uri_other_namespace\"> element in the 'any' bucket for typeExtendedC </xml-fragment>"}));

        // select attributes in the any bucket by excluding the the known attributes
        qnsb = new QNameSetBuilder();
        qnsb.add(new QName("", "att1"));
        qnsb.add(new QName("", "aditionalAtt"));
        qnsb.add(new QName(XSI_URI, "type"));
        qnsb.invert();

        //print("12a    selectChildren in the any bucket for typeExtendedC: " , xos[0].selectAttributes(qnsb.toQNameSet()));
        assertTrue("12a    selectChildren in the any bucket for typeExtendedC: ",
            verifyResult(xos[0].selectAttributes(qnsb.toQNameSet()),
                new String[]{"<xml-fragment xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:p=\"uri_other_namespace\">attribute in any bucket</xml-fragment>"}));
        //print("12b    selectChildren in the any bucket for typeExtendedC: " , xos[0].selectAttributes(TypeExtendedC.type.qnameSetForWildcardAttributes()));
        assertTrue("12b    selectChildren in the any bucket for typeExtendedC: ",
            verifyResult(xos[0].selectAttributes(TypeExtendedC.type.qnameSetForWildcardAttributes()),
                new String[]{"<xml-fragment xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:p=\"uri_other_namespace\">typeExtendedC</xml-fragment>",
                    "<xml-fragment xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:p=\"uri_other_namespace\">attribute in any bucket</xml-fragment>"}));
    }

    private static void printErrors(Collection errors) {
        for (Iterator i = errors.iterator(); i.hasNext(); ) {
            System.out.println("ERROR: " + i.next());
        }
    }

    private static boolean verifyResult(XmlObject[] xos, String[] expected) {
        if (xos == null && expected == null)
            return true;

        if (xos == null || expected == null)
            return false;

        if (xos.length != expected.length)
            return false;

        for (int i = 0; i < xos.length; i++) {
            XmlObject xo = xos[i];
            if (!equalsIgnoreNewLine(xo.toString(), expected[i])) {
                System.out.println("ERROR:\n    Actual:\n" + xo.toString() + "\n   Expected:\n" + expected[i]);
                return false;
            }
        }
        return true;
    }

    private static boolean verifyResult(XmlObject xo, String expected) {
        if (xo == null && expected == null)
            return true;

        if (xo == null || expected == null)
            return false;

        if (!xo.toString().equals(expected)) {
            System.out.println("ERROR:\n    Actual:\n" + xo.toString() + "\n   Expected:\n" + expected);
            return false;
        } else
            return true;
    }

    private static boolean equalsIgnoreNewLine(String s1, String s2) {
        if (s1 == null && s2 == null)
            return true;

        if (s1 == null || s2 == null)
            return false;

        int i1 = 0, i2 = 0;
        while (i1 < s1.length() || i2 < s2.length()) {
            if (s1.charAt(i1) == '\n' || s1.charAt(i1) == '\r') {
                i1++;
                continue;
            }

            if (s2.charAt(i2) == '\n' || s2.charAt(i2) == '\r') {
                i2++;
                continue;
            }

            if (s1.charAt(i1) != s2.charAt(i2))
                return false;

            i1++;
            i2++;
        }

        return (i1 == s1.length()) && (i2 == s2.length());
    }
}
