/*
 * Copyright (c) 1998, 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.jaxbcontext;

import java.io.InputStream;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.net.URL;
import java.util.*;

import jakarta.xml.bind.*;
import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilderFactory;

import org.eclipse.persistence.exceptions.SessionLoaderException;
import org.eclipse.persistence.exceptions.ValidationException;
import org.eclipse.persistence.jaxb.JAXBContextFactory;
import org.eclipse.persistence.jaxb.JAXBContextProperties;
import org.eclipse.persistence.jaxb.TypeMappingInfo;
import org.eclipse.persistence.jaxb.javamodel.reflection.JavaClassImpl;
import org.eclipse.persistence.testing.oxm.classloader.JARClassLoader;
import org.w3c.dom.Document;

public class JaxbContextCreationTests extends junit.framework.TestCase {

    @Override
    public String getName() {
        return "JAXB Context Creation Tests: " + super.getName();
    }

    public void testCreateContextWithObjectFactory() throws Exception {
        JAXBContext context = JAXBContextFactory.createContext("org.eclipse.persistence.testing.jaxb.jaxbcontext", Thread.currentThread().getContextClassLoader());
    }

    public void testCreateContextNoClassesOrSessions() throws Exception {
        try {
            JAXBContext context = JAXBContextFactory.createContext("org.eclipse.persistence.testing.jaxb.jaxbcontext.fake", Thread.currentThread().getContextClassLoader());
        } catch(JAXBException ex) {
            assertTrue(((org.eclipse.persistence.exceptions.JAXBException)ex.getLinkedException()).getErrorCode() == org.eclipse.persistence.exceptions.JAXBException.NO_OBJECT_FACTORY_OR_JAXB_INDEX_IN_PATH);
            assertTrue(((org.eclipse.persistence.exceptions.JAXBException)ex.getLinkedException()).getInternalException() instanceof ValidationException);
        }
    }

    public void testCreateContextUnrelatedSessionsXml() throws Exception {
        JAXBContext context = JAXBContextFactory.createContext("org.eclipse.persistence.testing.jaxb.jaxbcontext", new ClassLoader() {
            @Override
            public URL getResource(String resourceName) {
                if(resourceName.equals("sessions.xml")) {
                    return getParent().getResource("org/eclipse/persistence/testing/jaxb/jaxbcontext/sessions.xml");
                }
                return this.getParent().getResource(resourceName);
            }
        });
    }

    public void testCreateContextUnrelatedSessionsXmlInvalidPath() throws Exception {
        try {
            JAXBContext context = JAXBContextFactory.createContext("org.eclipse.persistence.testing.jaxb.jaxbcontext.fake", new ClassLoader() {
                @Override
                public URL getResource(String resourceName) {
                    if(resourceName.equals("sessions.xml")) {
                        return getParent().getResource("org/eclipse/persistence/testing/jaxb/jaxbcontext/sessions.xml");
                    }
                    return this.getParent().getResource(resourceName);
                }
            });
        } catch(JAXBException ex) {
            assertTrue(((org.eclipse.persistence.exceptions.JAXBException)ex.getLinkedException()).getErrorCode() == org.eclipse.persistence.exceptions.JAXBException.NO_OBJECT_FACTORY_OR_JAXB_INDEX_IN_PATH);
            assertTrue(((org.eclipse.persistence.exceptions.JAXBException)ex.getLinkedException()).getInternalException() instanceof SessionLoaderException);
        }
    }

    public void testCreateContextWithStringClass() throws JAXBException {
        Class[] classes = new Class[1];
        classes[0] = String.class;
        JAXBContextFactory.createContext(classes, null);
    }

    public void testCreateContextWithIntArrayClass() throws JAXBException {
        Class[] classes = new Class[1];
        int[] ints = new int[1];
        classes[0] = ints.getClass();
        JAXBContextFactory.createContext(classes, null);
    }

    public void testCreateContextWith_ClassArray_NullClassLoader() throws JAXBException {
        Class[] classes = new Class[1];
        int[] ints = new int[1];
        classes[0] = ints.getClass();
        JAXBContextFactory.createContext(classes, null);
    }

    public void testCreateContextWith_ClassArray_Map_NullClassLoader_Map() throws JAXBException {
        Class[] classes = new Class[1];
        int[] ints = new int[1];
        classes[0] = ints.getClass();
        JAXBContextFactory.createContext(classes, null, null);
    }

    public void testCreateContextWith_String_NullClassLoader() throws JAXBException {
        JAXBContextFactory.createContext("org.eclipse.persistence.testing.jaxb.jaxbcontext", null);
    }

    public void testCreateContextWith_String_NullClassLoader_Map() throws JAXBException {
        JAXBContextFactory.createContext("org.eclipse.persistence.testing.jaxb.jaxbcontext", null, null);
    }

    public void testCreateContextWith_TypeArray_Map_NullClassLoader() throws JAXBException {
        Type[] types = new Type[1];
        types[0] = List.class;
        JAXBContextFactory.createContext(types, null, null);
    }

    public void testCreateContextWith_TypeMappingInfoArray_Map_NullClassLoader() throws JAXBException {
        TypeMappingInfo[] typeMappingInfos = new TypeMappingInfo[1];
        TypeMappingInfo listTMI = new TypeMappingInfo();
        listTMI.setType(List.class);
        listTMI.setXmlTagName(new QName("urn:example", "my-list"));
        typeMappingInfos[0] = listTMI;
        JAXBContextFactory.createContext(typeMappingInfos, null, null);
    }

    public void testCreateAbstractClassWithMultiArgConstructor() throws JAXBException {
        Class[] classes = new Class[1];
        classes[0] = AbstractClassWithMultiArgConstructor.class;
        JAXBContextFactory.createContext(classes, null);
    }

    public void testCreateConcreteClassWithMultiArgConstructor() throws JAXBException {
        try {
            Class[] classes = new Class[1];
            classes[0] = ConcreteClassWithMultiArgConstructor.class;
            JAXBContextFactory.createContext(classes, null);
        } catch(JAXBException e) {
            org.eclipse.persistence.exceptions.JAXBException je = (org.eclipse.persistence.exceptions.JAXBException) e.getLinkedException();
            assertEquals(org.eclipse.persistence.exceptions.JAXBException.FACTORY_METHOD_OR_ZERO_ARG_CONST_REQ, je.getErrorCode());
            return;
        }
        fail();
    }

    public void testCreateContextWithGenerics() throws JAXBException {
        Class[] classes = new Class[1];
        classes[0] = ConcreteClassWithGenerics.class;
        JAXBContextFactory.createContext(classes, null);
    }

    public void testCreateContextWithPathAndBindings() throws Exception {
        String oxmString = "org/eclipse/persistence/testing/jaxb/jaxbcontext/eclipselink-oxm.xml";
        InputStream oxm = ClassLoader.getSystemClassLoader().getResourceAsStream(oxmString);

        Map<String, Object> props = new HashMap<String, Object>();
        props.put(JAXBContextProperties.OXM_METADATA_SOURCE, oxm);

        // Specify some other, unrelated context path -- we want to ensure that we don't fail
        // due to lack of ObjectFactory/jaxb.index
        JAXBContext ctx = JAXBContext.newInstance("org.eclipse.persistence.testing.oxm.jaxb",
                ClassLoader.getSystemClassLoader(), props);

        Employee e = new Employee();
        e.id = 6;
        e.name = "Jeeves Sobs";
        e.put("tag", "tag-value");

        Document marshalDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();

        Marshaller m = ctx.createMarshaller();
        m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        m.marshal(e, marshalDoc);

        // Make sure OXM was picked up, "tag" property should have been added.
        Employee e2 = (Employee) ctx.createUnmarshaller().unmarshal(marshalDoc);
        assertEquals("OXM file was not processed during context creation.", e.get("tag"), e2.get("tag"));
    }

    public void testCreateContextXmlAnyAttributeSubTypeMap() throws Exception {
        JAXBContextFactory.createContext(new Class[]{XmlAnyAttributeSubTypeMapModel.class}, null);
    }

    public void testJavaClassImplWildcard() throws Exception{
        ParameterizedType pType = (ParameterizedType) WildCardTest.class.getField("testField").getGenericType();
        JavaClassImpl javaClass = new JavaClassImpl(pType, java.util.List.class, null);
        boolean hasArgs = javaClass.hasActualTypeArguments();
        Collection getArgs = javaClass.getActualTypeArguments();
        assertFalse(hasArgs);
        assertTrue(getArgs.size()== 0);
    }

    /**
     * Test creating a context with classes generated from the GML/XLink schemas.  Tests
     * that a class with both ns0:title and @ns0:title mappings is interpreted properly.
     */
    public void testCreateContextXLink() throws Exception {
        JAXBContext context = JAXBContext.newInstance(this.getClass().getPackage().getName() + ".xlink");
        assertNotNull(context);
    }

}
