/*
 * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.testing.oxm.mappings.anycollection.withgroupingelement;

import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;
import java.util.Vector;

import junit.textui.TestRunner;

import org.eclipse.persistence.oxm.XMLConstants;
import org.eclipse.persistence.oxm.XMLDescriptor;
import org.eclipse.persistence.oxm.XMLRoot;
import org.eclipse.persistence.oxm.mappings.XMLAnyCollectionMapping;
import org.eclipse.persistence.oxm.schema.XMLSchemaClassPathReference;
import org.eclipse.persistence.sessions.Project;
import org.eclipse.persistence.testing.oxm.mappings.XMLWithJSONMappingTestCases;

public class AnyCollectionWithGroupingWithXMLRootTestCases extends XMLWithJSONMappingTestCases {
    public AnyCollectionWithGroupingWithXMLRootTestCases(String name) throws Exception {
        super(name);
        Project project = new AnyCollectionWithGroupingElementProjectNS();
        ((XMLAnyCollectionMapping) project.getDescriptor(Root.class).getMappingForAttributeName("any")).setUseXMLRoot(true);

        XMLSchemaClassPathReference schemaRef = new XMLSchemaClassPathReference();
        schemaRef.setSchemaContext("/myns:childType");
        schemaRef.setType(XMLSchemaClassPathReference.COMPLEX_TYPE);
        ((XMLDescriptor)project.getDescriptor(Child.class)).setSchemaReference(schemaRef);
        setProject(project);
        setControlDocument("org/eclipse/persistence/testing/oxm/mappings/anycollection/withgroupingelement/complex_children_ns_xmlroot.xml");
        setControlJSON("org/eclipse/persistence/testing/oxm/mappings/anycollection/withgroupingelement/complex_children_ns_xmlroot.json");
    }

    @Override
    protected Map<String, String> getNamespaces() {
        Map<String, String> namespaces = new HashMap<String, String>();
        namespaces.put("www.example.com/some-dir/some.xsd", "myns");
        namespaces.put(javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "xsi");
        return namespaces;
    }

    @Override
    public Object getControlObject() {
        Root root = new Root();
        Vector any = new Vector();
        any.add("myTextNode");

        Child child = new Child();
        child.setContent("Child1");
        any.addElement(child);
        child = new Child();
        child.setContent("Child2");
        any.addElement(child);

        /*XMLRoot xmlroot0 = new XMLRoot();
        //xmlroot0.setObject((String)null);
        xmlroot0.setObject("");
        xmlroot0.setObject("  ");
        xmlroot0.setRootElementName("myns:emptyValueElement");
        xmlroot0.setRootElementURI("www.example.com/some-dir/some.xsd");
        any.addElement(xmlroot0);*/



        XMLRoot xmlroot2 = new XMLRoot();

        xmlroot2.setObject(15);
        //xmlroot2.setObject("15");
        xmlroot2.setLocalName("myns:theInteger");
        xmlroot2.setNamespaceURI("www.example.com/some-dir/some.xsd");
        xmlroot2.setSchemaType(XMLConstants.INT_QNAME);
        any.addElement(xmlroot2);

         XMLRoot xmlroot1 = new XMLRoot();
        xmlroot1.setObject("15");
        xmlroot1.setLocalName("myns:theString");
        xmlroot1.setNamespaceURI("www.example.com/some-dir/some.xsd");
        any.addElement(xmlroot1);

        XMLRoot next = new XMLRoot();

        Calendar theCalendar  =Calendar.getInstance();
        theCalendar.clear();
        theCalendar.set(Calendar.HOUR, 9);
        theCalendar.set(Calendar.HOUR_OF_DAY, 9);
        theCalendar.set(Calendar.AM_PM, Calendar.AM);
        theCalendar.set(Calendar.MINUTE, 30);
        theCalendar.set(Calendar.SECOND, 45);
        theCalendar.set(Calendar.MILLISECOND, 0);
        next.setSchemaType(XMLConstants.TIME_QNAME);

        next.setObject(theCalendar);
        next.setNamespaceURI("www.example.com/some-dir/some.xsd");
        next.setLocalName("theTime");
        any.addElement(next);

        XMLRoot xmlroot3 = new XMLRoot();
        child = new Child();
        child.setContent("Child3");
        xmlroot3.setObject(child);
        xmlroot3.setLocalName("myns:someChild");
        xmlroot3.setNamespaceURI("www.example.com/some-dir/some.xsd");
        any.addElement(xmlroot3);

        XMLRoot xmlroot4 = new XMLRoot();
        child = new Child();
        child.setContent("Child4");
        xmlroot4.setObject(child);
        xmlroot4.setLocalName("myns:blah");
        xmlroot4.setNamespaceURI("www.example.com/some-dir/some.xsd");
        any.addElement(xmlroot4);

        XMLRoot xmlroot5 = new XMLRoot();
        child = new Child();
        xmlroot5.setObject(child);
        xmlroot5.setLocalName("myns:someChild");
        xmlroot5.setNamespaceURI("www.example.com/some-dir/some.xsd");
        any.addElement(xmlroot5);

        root.setAny(any);
        return root;
    }

    @Override
    public Object getJSONReadControlObject(){
        //different order - mixed always last and same qnames grouped together, no namespaces

           Root root = new Root();
           Vector any = new Vector();

           Child child = new Child();
           child.setContent("Child1");
           any.addElement(child);
           child = new Child();
           child.setContent("Child2");
           any.addElement(child);


           XMLRoot xmlroot2 = new XMLRoot();

           xmlroot2.setObject(15);
           //xmlroot2.setObject("15");
           xmlroot2.setLocalName("theInteger");
           xmlroot2.setNamespaceURI("www.example.com/some-dir/some.xsd");
           xmlroot2.setSchemaType(XMLConstants.INT_QNAME);
           any.addElement(xmlroot2);

            XMLRoot xmlroot1 = new XMLRoot();
           xmlroot1.setObject("15");
           xmlroot1.setLocalName("theString");
           xmlroot1.setNamespaceURI("www.example.com/some-dir/some.xsd");
           any.addElement(xmlroot1);

           XMLRoot next = new XMLRoot();

           Calendar theCalendar  =Calendar.getInstance();
           theCalendar.clear();
           theCalendar.set(Calendar.HOUR, 9);
           theCalendar.set(Calendar.HOUR_OF_DAY, 9);
           theCalendar.set(Calendar.AM_PM, Calendar.AM);
           theCalendar.set(Calendar.MINUTE, 30);
           theCalendar.set(Calendar.SECOND, 45);
           theCalendar.set(Calendar.MILLISECOND, 0);
           next.setSchemaType(XMLConstants.TIME_QNAME);

           next.setObject(theCalendar);
           next.setLocalName("theTime");
           next.setNamespaceURI("www.example.com/some-dir/some.xsd");
           any.addElement(next);

           XMLRoot xmlroot3 = new XMLRoot();
           child = new Child();
           child.setContent("Child3");
           xmlroot3.setObject(child);
           xmlroot3.setLocalName("someChild");
           xmlroot3.setNamespaceURI("www.example.com/some-dir/some.xsd");
           any.addElement(xmlroot3);

           XMLRoot xmlroot5 = new XMLRoot();
           child = new Child();
           xmlroot5.setObject(child);
           xmlroot5.setLocalName("someChild");
           xmlroot5.setNamespaceURI("www.example.com/some-dir/some.xsd");
           any.addElement(xmlroot5);

           XMLRoot xmlroot4 = new XMLRoot();
           child = new Child();
           child.setContent("Child4");
           xmlroot4.setObject(child);
           xmlroot4.setLocalName("blah");
           xmlroot4.setNamespaceURI("www.example.com/some-dir/some.xsd");
           any.addElement(xmlroot4);

           any.add("myTextNode");


           root.setAny(any);
           return root;
    }

    public static void main(String[] args) {
        String[] arguments = { "-c", "org.eclipse.persistence.testing.oxm.mappings.anycollection.withgroupingelement.AnyCollectionWithGroupingWithXMLRootTestCases" };
        TestRunner.main(arguments);
    }
}
