/*
 * 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:
//     rbarkhouse - 2.1 - initial implementation
package org.eclipse.persistence.testing.jaxb.dynamic;

import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

import jakarta.xml.bind.JAXBContext;
import jakarta.xml.bind.JAXBElement;
import jakarta.xml.bind.Marshaller;
import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;

import junit.framework.TestCase;

import org.eclipse.persistence.dynamic.DynamicEntity;
import org.eclipse.persistence.jaxb.*;
import org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContext;
import org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContextFactory;
import org.eclipse.persistence.oxm.NamespaceResolver;
import org.w3c.dom.Document;

public class DynamicJAXBUsingXMLNamesTestCases extends TestCase {

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

    @Override
    public String getName() {
        return "Dynamic JAXB: Using XML Names: " + super.getName();
    }

    public void testCreateEntityByXMLName() throws Exception {
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();

        InputStream iStream = classLoader.getResourceAsStream(EXAMPLE_OXM);
        if (iStream == null) {
            fail("Couldn't load metadata file [" + EXAMPLE_OXM + "]");
        }
        HashMap<String, Source> metadataSourceMap = new HashMap<String, Source>();
        metadataSourceMap.put("org.eclipse.persistence.testing.jaxb.dynamic", new StreamSource(iStream));

        Map<String, Map<String, Source>> properties = new HashMap<String, Map<String, Source>>();
        properties.put(JAXBContextProperties.OXM_METADATA_SOURCE, metadataSourceMap);

        DynamicJAXBContext jaxbContext = (DynamicJAXBContext) JAXBContext.newInstance("org.eclipse.persistence.testing.jaxb.dynamic", classLoader, properties);
        DynamicEntity employee = (DynamicEntity) jaxbContext.createByQualifiedName(EMPLOYEE_NAMESPACE, EMPLOYEE_TYPE_NAME, false);
        assertNotNull("Could not create Dynamic Entity.", employee);

        NamespaceResolver nsResolver = new NamespaceResolver();
        nsResolver.put("ns0", "mynamespace");

        jaxbContext.setValueByXPath(employee, "name/text()", nsResolver, "Larry King");
        jaxbContext.setValueByXPath(employee, "employee-id/text()", nsResolver, "CA34287");

        Document marshalDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
        jaxbContext.createMarshaller().marshal(employee, marshalDoc);

        DynamicEntity employee2 = (DynamicEntity) jaxbContext.createUnmarshaller().unmarshal(marshalDoc);
        String newName = jaxbContext.getValueByXPath(employee2, "name/text()", nsResolver, String.class);
        String newId = jaxbContext.getValueByXPath(employee2, "employee-id/text()", nsResolver, String.class);

        assertEquals("Larry King", newName);
        assertEquals("CA34287", newId);
    }

    public void testCreateEntityByXMLNameJSON() throws Exception {
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();

        InputStream iStream = classLoader.getResourceAsStream(EXAMPLE_OXM);
        if (iStream == null) {
            fail("Couldn't load metadata file [" + EXAMPLE_OXM + "]");
        }
        HashMap<String, Source> metadataSourceMap = new HashMap<String, Source>();
        metadataSourceMap.put("org.eclipse.persistence.testing.jaxb.dynamic", new StreamSource(iStream));

        Map<String, Map<String, Source>> properties = new HashMap<String, Map<String, Source>>();
        properties.put(JAXBContextProperties.OXM_METADATA_SOURCE, metadataSourceMap);

        DynamicJAXBContext jaxbContext = (DynamicJAXBContext) JAXBContext.newInstance("org.eclipse.persistence.testing.jaxb.dynamic", classLoader, properties);
        DynamicEntity employee = (DynamicEntity) jaxbContext.createByQualifiedName(EMPLOYEE_NAMESPACE, EMPLOYEE_TYPE_NAME, false);
        assertNotNull("Could not create Dynamic Entity.", employee);

        NamespaceResolver nsResolver = new NamespaceResolver();
        nsResolver.put("ns0", "mynamespace");

        jaxbContext.setValueByXPath(employee, "name/text()", nsResolver, "Larry King");
        jaxbContext.setValueByXPath(employee, "employee-id/text()", nsResolver, "CA34287");

        JAXBMarshaller m = jaxbContext.createMarshaller();
        m.setProperty(MarshallerProperties.MEDIA_TYPE, "application/json");
        Document marshalDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();

        m.marshal(employee, marshalDoc);

        JAXBUnmarshaller u = jaxbContext.createUnmarshaller();
        u.setProperty(UnmarshallerProperties.MEDIA_TYPE, "application/json");
        DynamicEntity employee2 = (DynamicEntity) u.unmarshal(marshalDoc);
        String newName = jaxbContext.getValueByXPath(employee2, "name/text()", nsResolver, String.class);
        String newId = jaxbContext.getValueByXPath(employee2, "employee-id/text()", nsResolver, String.class);

        assertEquals("Larry King", newName);
        assertEquals("CA34287", newId);

    }

    public void testCreateEntityByXPathNameCollision1() throws Exception {
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();

        InputStream iStream = classLoader.getResourceAsStream(EXAMPLE_XSD_2);
        if (iStream == null) {
            fail("Couldn't load metadata file [" + EXAMPLE_XSD_2 + "]");
        }

        Map<String, InputStream> properties = new HashMap<String, InputStream>();
        properties.put(DynamicJAXBContextFactory.XML_SCHEMA_KEY, iStream);

        DynamicJAXBContext jaxbContext = (DynamicJAXBContext) JAXBContext.newInstance("org.eclipse.persistence.testing.jaxb.dynamic", classLoader, properties);
        DynamicEntity person = (DynamicEntity) jaxbContext.createByQualifiedName("mynamespace", "person", true);
        assertNotNull("Could not create Dynamic Entity.", person);

        NamespaceResolver nsResolver = new NamespaceResolver();
        nsResolver.put("ns0", "mynamespace");

        jaxbContext.setValueByXPath(person, "ns0:full_name/text()", nsResolver, "Larry King");

        Document marshalDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
        JAXBElement jbe = new JAXBElement(new QName("person"), DynamicEntity.class, person);
        jaxbContext.createMarshaller().marshal(jbe, marshalDoc);

        DynamicEntity person2 = ((JAXBElement<DynamicEntity>) jaxbContext.createUnmarshaller().unmarshal(marshalDoc)).getValue();
        String newName = jaxbContext.getValueByXPath(person2, "ns0:full_name/text()", nsResolver, String.class);

        assertEquals("Larry King", newName);
    }

    public void testCreateEntityByXPathNameCollision2() throws Exception {
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();

        InputStream iStream = classLoader.getResourceAsStream(EXAMPLE_XSD_2);
        if (iStream == null) {
            fail("Couldn't load metadata file [" + EXAMPLE_XSD_2 + "]");
        }

        Map<String, InputStream> properties = new HashMap<String, InputStream>();
        properties.put(DynamicJAXBContextFactory.XML_SCHEMA_KEY, iStream);

        NamespaceResolver nsResolver = new NamespaceResolver();
        nsResolver.put("ns0", "mynamespace");

        DynamicJAXBContext jaxbContext = (DynamicJAXBContext) JAXBContext.newInstance("org.eclipse.persistence.testing.jaxb.dynamic", classLoader, properties);
        DynamicEntity person = (DynamicEntity) jaxbContext.createByQualifiedName("mynamespace", "person", false);
        assertNotNull("Could not create Dynamic Entity.", person);

        // Set name by XPath
        jaxbContext.setValueByXPath(person, "ns0:first-name/text()", nsResolver, "Larry");

        // Create address by XPath, set street by XPath
        DynamicEntity address = jaxbContext.createByXPath(person, "ns0:address", nsResolver, DynamicEntity.class);
        jaxbContext.setValueByXPath(address, "ns0:street/text()", nsResolver, "400 CNN Plaza");

        // Create person's address by XPath
        jaxbContext.setValueByXPath(person, "ns0:address", nsResolver, address);

        Document marshalDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
        jaxbContext.createMarshaller().marshal(person, marshalDoc);

        DynamicEntity person2 = (DynamicEntity) jaxbContext.createUnmarshaller().unmarshal(marshalDoc);
        DynamicEntity address2 = jaxbContext.getValueByXPath(person2, "ns0:address", nsResolver, DynamicEntity.class);
        String newName = jaxbContext.getValueByXPath(person2, "ns0:first-name/text()", nsResolver, String.class);
        String newStreet = jaxbContext.getValueByXPath(address2, "ns0:street/text()", nsResolver, String.class);
        String newStreet2 = jaxbContext.getValueByXPath(person2, "ns0:address/ns0:street/text()", nsResolver, String.class);

        assertEquals("Larry", newName);
        assertEquals("400 CNN Plaza", newStreet);
        assertEquals("400 CNN Plaza", newStreet2);
    }

    private void print(Object o, JAXBContext jaxbContext) throws Exception {
        Marshaller marshaller = jaxbContext.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
        marshaller.marshal(o, System.err);
    }

    private static final String SESSION_NAMES =
        "org.eclipse.persistence.testing.jaxb.dynamic:org.eclipse.persistence.testing.jaxb.dynamic.secondproject";

    private static final String EXAMPLE_XSD =
        "org/eclipse/persistence/testing/jaxb/dynamic/contextcreation.xsd";
    private static final String EXAMPLE_XSD_2 =
        "org/eclipse/persistence/testing/jaxb/dynamic/contextcreation2.xsd";
    private static final String EXAMPLE_OXM =
        "org/eclipse/persistence/testing/jaxb/dynamic/contextcreation-oxm.xml";

    private static final String EMPLOYEE_CLASS_NAME =
        "mynamespace.Employee";
    private static final String EMPLOYEE_NAMESPACE = "mynamespace";
    private static final String EMPLOYEE_TYPE_NAME = "employee-data";
    private static final String PERSON_CLASS_NAME =
        "org.eclipse.persistence.testing.jaxb.dynamic.Person";

}
