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

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";

    @Override
    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());
    }

}
