/*
 * Copyright (c) 2011, 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:
//     Rick Barkhouse - 2.3.1 - initial implementation
package org.eclipse.persistence.testing.jaxb.externalizedmetadata.namespace;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import jakarta.xml.bind.JAXBContext;
import jakarta.xml.bind.Marshaller;
import jakarta.xml.bind.Unmarshaller;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.eclipse.persistence.jaxb.JAXBContextFactory;
import org.eclipse.persistence.jaxb.JAXBContextProperties;
import org.eclipse.persistence.testing.jaxb.JAXBTestCases;
import org.eclipse.persistence.testing.oxm.XMLTestCase;
import org.w3c.dom.Document;

/**
 * <p>Tests general XML Namespace operations when using EclipseLink XML Bindings.</p>
 */
public class NamespaceTestCases extends XMLTestCase {

    private static final String BINDINGS1 = "org/eclipse/persistence/testing/jaxb/externalizedmetadata/namespace/xml-bindings.xml";
    private static final String INSTANCE1 = "org/eclipse/persistence/testing/jaxb/externalizedmetadata/namespace/instance.xml";
    private static final String BINDINGS2 = "org/eclipse/persistence/testing/jaxb/externalizedmetadata/namespace/bindings-rootelement.xml";
    private static final String INSTANCE2 = "org/eclipse/persistence/testing/jaxb/externalizedmetadata/namespace/instance2.xml";

    public NamespaceTestCases(String name) throws Exception {
        super(name);
    }

    @Override
    public String getName() {
        return "ExternalizedMetadata - Namespace: " + super.getName();
    }

    private Object getControlObject() {
        Customer c = new Customer();
        c.id = 6;
        c.name = "Bob";
        c.account = "32847";

        return c;
    }

    /**
     * <p>Tests that basic namespace information is being interpreted at all three possible levels,
     * when bootstrapped from XML Bindings:</p>
     *
     * <ul>
     *  <li>Package-level (defined in &lt;xml-schema&gt;)</li>
     *  <li>Type-level (defined in &lt;xml-type&gt;)</li>
     *  <li>Property-level (defined in &lt;xml-element&gt;)</li>
     * </ul>
     */
    public void testBasicNamespaces() throws Exception {
        InputStream bindings = ClassLoader.getSystemResourceAsStream(BINDINGS1);
        Map<String, Object> properties = new HashMap<String, Object>();
        properties.put(JAXBContextProperties.OXM_METADATA_SOURCE, bindings);

        JAXBContext ctx = JAXBContextFactory.createContext(new Class<?>[]{ Customer.class }, properties);

        DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
        builderFactory.setNamespaceAware(true);
        DocumentBuilder parser = builderFactory.newDocumentBuilder();

        // Marshal control doc to Document
        Marshaller m = ctx.createMarshaller();
        Document marshalDoc = parser.newDocument();
        m.marshal(getControlObject(), marshalDoc);

        // Parse instance doc to Document
        InputStream iStream = ClassLoader.getSystemResourceAsStream(INSTANCE1);
        Document unmarshalDoc = parser.parse(iStream);

        // Compare
        assertXMLIdentical(unmarshalDoc, marshalDoc);
    }

    /**
     * Test that root elements that are in a non-default namespace are prefixed correctly.
     */
    public void testNonDefaultRootElement() throws Exception {
        InputStream bindings = ClassLoader.getSystemResourceAsStream(BINDINGS2);
        Map<String, Object> properties = new HashMap<String, Object>();
        properties.put(JAXBContextProperties.OXM_METADATA_SOURCE, bindings);

        JAXBContext ctx = JAXBContextFactory.createContext(new Class<?>[]{ Customer.class }, properties);

        DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
        builderFactory.setNamespaceAware(true);
        DocumentBuilder parser = builderFactory.newDocumentBuilder();

        Marshaller m = ctx.createMarshaller();
        Document marshalDoc = parser.newDocument();
        m.marshal(getControlObject(), marshalDoc);

        InputStream iStream = ClassLoader.getSystemResourceAsStream(INSTANCE2);
        Document unmarshalDoc = parser.parse(iStream);

        assertXMLIdentical(unmarshalDoc, marshalDoc);
    }

}
