/*
 * 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.JAXBContextProperties;
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(JAXBContextProperties.OXM_METADATA_SOURCE, 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());
    }

}
