/*
 * Copyright (c) 2018, 2020 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
 */

package org.eclipse.persistence.testing.jaxb.dynamic;

import java.io.InputStream;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import jakarta.xml.bind.JAXBContext;
import jakarta.xml.bind.JAXBElement;
import jakarta.xml.bind.Unmarshaller;
import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.eclipse.persistence.dynamic.DynamicEntity;
import org.eclipse.persistence.exceptions.JAXBException;
import org.eclipse.persistence.internal.dynamic.DynamicEntityImpl;
import org.eclipse.persistence.internal.dynamic.DynamicEntityImpl.PropertyWrapper;
import org.eclipse.persistence.jaxb.JAXBContextFactory;
import org.eclipse.persistence.jaxb.JAXBHelper;
import org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContext;
import org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContextFactory;
import org.eclipse.persistence.oxm.XMLDescriptor;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import junit.framework.TestCase;

public class DynamicJAXBRefreshTestCases extends TestCase {

    private static final String OXM_METADATA = "org/eclipse/persistence/testing/jaxb/dynamic/metadata.xml";
    private static final String XSD_METADATA = "org/eclipse/persistence/testing/jaxb/dynamic/refresh.xsd";
    private static final String XML_RESOURCE_BEFORE = "org/eclipse/persistence/testing/jaxb/dynamic/before.xml";
    private static final String XML_RESOURCE_AFTER = "org/eclipse/persistence/testing/jaxb/dynamic/after.xml";

    public String getName() {
        return "Dynamic JAXB: Metadata Refresh: " + super.getName();
    }

    public void testRefreshOXM() throws Exception {
        ClassLoader classLoader = this.getClass().getClassLoader();

        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        dbf.setNamespaceAware(true);
        DocumentBuilder db = dbf.newDocumentBuilder();
        InputStream metadataStream = classLoader.getResourceAsStream(OXM_METADATA);
        Document metadataDocument = db.parse(metadataStream);
        metadataStream.close();

        Map<String, Object> props = new HashMap<String, Object>(1);
        props.put(JAXBContextFactory.ECLIPSELINK_OXM_XML_KEY, metadataDocument);

        DynamicJAXBContext jc = DynamicJAXBContextFactory.createContextFromOXM(classLoader, props);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        DynamicEntity controlRoot = jc.newDynamicEntity("org.eclipse.persistence.testing.jaxb.dynamic.Root");
        controlRoot.set("name", "R");

        InputStream xmlBeforeStream = classLoader.getResourceAsStream(XML_RESOURCE_BEFORE);
        DynamicEntity rootBefore = (DynamicEntity) unmarshaller.unmarshal(xmlBeforeStream);
        assertEquals(controlRoot.get("name"), rootBefore.get("name"));

        Element xmlElementElement = (Element) metadataDocument.getElementsByTagNameNS("http://www.eclipse.org/eclipselink/xsds/persistence/oxm", "xml-element").item(0);
        xmlElementElement.setAttribute("name", "after-name");
        JAXBHelper.getJAXBContext(jc).refreshMetadata();

        InputStream xmlAfterStream = classLoader.getResourceAsStream(XML_RESOURCE_AFTER);
        DynamicEntity rootAfter = (DynamicEntity) unmarshaller.unmarshal(xmlAfterStream);
        assertEquals(controlRoot.get("name"), rootAfter.get("name"));
    }

    public void testRefreshSchemaNode() throws Exception {
        ClassLoader classLoader = this.getClass().getClassLoader();

        // Get XSD as Element
        InputStream inputStream = ClassLoader.getSystemResourceAsStream(XSD_METADATA);
        DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
        docFactory.setNamespaceAware(true);
        DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
        Document xsdDocument = docBuilder.parse(inputStream);
        Element xsdElement = xsdDocument.getDocumentElement();

        DynamicJAXBContext jc = DynamicJAXBContextFactory.createContextFromXSD(xsdElement, null, classLoader, null);

        DynamicEntity controlRoot = jc.newDynamicEntity("Root");
        Exception caughtException = null;
        try {
            controlRoot.set("age", "10");
        } catch (Exception e) {
            caughtException = e;
        }

        // Should have caught an exception because we haven't added 'age' to
        // the metadata yet
        assertNotNull(caughtException);

        // Modify METADATA and REFRESH
        Element newElem = xsdDocument.createElementNS("http://www.w3.org/2001/XMLSchema", "element");
        newElem.setAttribute("name", "age");
        newElem.setAttribute("type", "xs:string");
        Element sequence = (Element) xsdElement.getElementsByTagNameNS("http://www.w3.org/2001/XMLSchema", "sequence").item(0);
        sequence.appendChild(newElem);
        JAXBHelper.getJAXBContext(jc).refreshMetadata();

        caughtException = null;
        try {
            controlRoot.set("age", "10");
        } catch (Exception e) {
            caughtException = e;
        }

        // Should NOT have caught an exception because 'age'
        // is now available
        assertNull(caughtException);
    }

    public void testRefreshSchemaInputStream() throws Exception {
        ClassLoader classLoader = this.getClass().getClassLoader();

        InputStream metadataStream = classLoader.getResourceAsStream(XSD_METADATA);

        DynamicJAXBContext jc = DynamicJAXBContextFactory.createContextFromXSD(metadataStream, null, classLoader, null);

        Exception caughtException = null;
        try {
            JAXBHelper.getJAXBContext(jc).refreshMetadata();
        } catch (Exception e) {
            caughtException = e;
        }

        assertNotNull("Refresh Exception was not thrown as expected.", caughtException);
        assertEquals("Incorrect exception thrown.", JAXBException.class, caughtException.getClass());
        assertEquals("Incorrect exception thrown.", JAXBException.CANNOT_REFRESH_METADATA, ((JAXBException) caughtException).getErrorCode());
    }

}
