/*
 * 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
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.jaxb;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.lang.reflect.Type;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import jakarta.xml.bind.JAXBElement;
import jakarta.xml.bind.JAXBException;
import jakarta.xml.bind.Unmarshaller;
import jakarta.xml.bind.helpers.DefaultValidationEventHandler;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLStreamReader;
import javax.xml.transform.Source;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamSource;

import org.eclipse.persistence.jaxb.JAXBContext.JAXBContextInput;
import org.eclipse.persistence.jaxb.JAXBContext.ContextPathInput;
import org.eclipse.persistence.jaxb.JAXBContext.TypeMappingInfoInput;
import org.eclipse.persistence.jaxb.compiler.CompilerHelper;
import org.eclipse.persistence.jaxb.compiler.XMLProcessor;
import org.eclipse.persistence.jaxb.metadata.MetadataSource;
import org.eclipse.persistence.jaxb.xmlmodel.XmlBindings;
import org.eclipse.persistence.oxm.MediaType;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;

/**
 * <p>
 * <b>Purpose:</b>An EclipseLink specific JAXBContextFactory. This class can be specified in a
 * jaxb.properties file to make use of EclipseLink's JAXB 2.1 implementation.
 * <p>
 * <b>Responsibilities:</b>
 * <ul>
 * <li>Create a JAXBContext from an array of Classes and a Properties object</li>
 * <li>Create a JAXBContext from a context path and a classloader</li>
 * </ul>
 * <p>
 * This class is the entry point into in EclipseLink's JAXB 2.1 Runtime. It provides the required
 * factory methods and is invoked by jakarta.xml.bind.JAXBContext.newInstance() to create new
 * instances of JAXBContext. When creating a JAXBContext from a contextPath, the list of classes is
 * derived either from an ObjectFactory class (schema-to-java) or a jaxb.index file
 * (java-to-schema).
 *
 * @author mmacivor
 * @see jakarta.xml.bind.JAXBContext
 * @see org.eclipse.persistence.jaxb.JAXBContext
 * @see org.eclipse.persistence.jaxb.compiler.Generator
 */
public class JAXBContextFactory {

    /**
     * @deprecated As of release 2.4, replaced by JAXBContextProperties.OXM_METADATA_SOURCE
     * @see org.eclipse.persistence.jaxb.JAXBContextProperties#OXM_METADATA_SOURCE
     */
    @Deprecated
    public static final String ECLIPSELINK_OXM_XML_KEY = "eclipselink-oxm-xml";
    /**
     * @deprecated As of release 2.4, replaced by JAXBContextProperties.DEFAULT_TARGET_NAMESPACE
     * @see org.eclipse.persistence.jaxb.JAXBContextProperties#DEFAULT_TARGET_NAMESPACE
     */
    @Deprecated
    public static final String DEFAULT_TARGET_NAMESPACE_KEY = "defaultTargetNamespace";
    /**
     * @deprecated As of release 2.4, replaced by JAXBContextProperties.ANNOTATION_HELPER
     * @see org.eclipse.persistence.jaxb.JAXBContextProperties#ANNOTATION_HELPER
     */
    @Deprecated
    public static final String ANNOTATION_HELPER_KEY = "annotationHelper";
    public static final String PKG_SEPARATOR = ".";

    /**
     * Create a JAXBContext on the array of Class objects.  The JAXBContext will
     * also be aware of classes reachable from the classes in the array.
     */
    public static jakarta.xml.bind.JAXBContext createContext(Class[] classesToBeBound, Map properties) throws JAXBException {
        ClassLoader loader = null;
        if (classesToBeBound.length > 0) {
            loader = classesToBeBound[0].getClassLoader();
        }
        return createContext(classesToBeBound, properties, loader);
    }

    /**
     * Create a JAXBContext on the array of Class objects.  The JAXBContext will
     * also be aware of classes reachable from the classes in the array.
     */
    public static jakarta.xml.bind.JAXBContext createContext(Class[] classesToBeBound, Map properties, ClassLoader classLoader) throws JAXBException {
        Type[] types = new Type[classesToBeBound.length];
        System.arraycopy(classesToBeBound, 0, types, 0, classesToBeBound.length);
        return createContext(types, properties, classLoader);
    }

    /**
     * Create a JAXBContext on context path.  The JAXBContext will
     * also be aware of classes reachable from the classes on the context path.
     */
    public static jakarta.xml.bind.JAXBContext createContext(String contextPath, ClassLoader classLoader) throws JAXBException {
        return createContext(contextPath, classLoader, null);
    }

    /**
     * Create a JAXBContext on context path.  The JAXBContext will
     * also be aware of classes reachable from the classes on the context path.
     */
    public static jakarta.xml.bind.JAXBContext createContext(String contextPath, ClassLoader classLoader, Map properties) throws JAXBException {
        JAXBContextInput contextInput = new ContextPathInput(contextPath, properties, classLoader);
        JAXBContext context = new JAXBContext(contextInput);
        if (context.isRefreshable()) {
            context.postInitialize();
        }
        return context;
    }

    /**
     * Create a JAXBContext on the array of Type objects.  The JAXBContext will
     * also be aware of classes reachable from the types in the array.  The
     * preferred means of creating a Type aware JAXBContext is to create the
     * JAXBContext with an array of TypeMappingInfo objects.
     */
    public static jakarta.xml.bind.JAXBContext createContext(Type[] typesToBeBound, Map properties, ClassLoader classLoader) throws JAXBException {
        Map<Type, TypeMappingInfo> typeToTypeMappingInfo = new HashMap<Type, TypeMappingInfo>();
        TypeMappingInfo[] typeMappingInfos = new TypeMappingInfo[typesToBeBound.length];
        for(int i = 0; i < typesToBeBound.length; i++) {
            TypeMappingInfo tmi = new TypeMappingInfo();
            tmi.setType(typesToBeBound[i]);
            typeToTypeMappingInfo.put(typesToBeBound[i], tmi);
            typeMappingInfos[i] = tmi;
        }

        JAXBContext context = (JAXBContext)createContext(typeMappingInfos, properties, classLoader);
        context.setTypeToTypeMappingInfo(typeToTypeMappingInfo);

        return context;
    }

    /**
     * Create a JAXBContext on the array of TypeMappingInfo objects.  The
     * JAXBContext will also be aware of classes reachable from the types in the
     * array.  This is the preferred means of creating a Type aware JAXBContext.
     */
    public static jakarta.xml.bind.JAXBContext createContext(TypeMappingInfo[] typesToBeBound, Map properties, ClassLoader classLoader) throws JAXBException {
        JAXBContextInput contextInput = new TypeMappingInfoInput(typesToBeBound, properties, classLoader);
        JAXBContext context = new JAXBContext(contextInput);
        if (context.isRefreshable()) {
            context.postInitialize();
        }
        return context;
    }

    /**
     * <p>Convenience method for processing a properties map and creating a map of
     * package names to XmlBindings instances.</p>
     *
     * <p>It is assumed that the given map's key will be JAXBContextProperties.OXM_METADATA_SOURCE,
     * and the value will be:</p>
     * <pre>
     * 1)  {@literal Map<String, Object>}
     *     - Object is one of those listed in 3) below
     * 2)  {@literal List<Object>}
     *     - Object is one of those listed in 3) below
     *     - Bindings file must contain package-name attribute on
     *       xml-bindings element
     * 3)  One of:
     *     - java.io.File
     *     - java.io.InputStream
     *     - java.io.Reader
     *     - java.lang.String
     *     - java.net.URL
     *     - javax.xml.stream.XMLEventReader
     *     - javax.xml.stream.XMLStreamReader
     *     - javax.xml.transform.Source
     *     - org.eclipse.persistence.jaxb.metadata.MetadataSource
     *     - org.w3c.dom.Node
     *     - org.xml.sax.InputSource
     *
     *     - Bindings file must contain package-name attribute on
     *       xml-bindings element
     * </pre>
     */
    public static Map<String, XmlBindings> getXmlBindingsFromProperties(Map properties, ClassLoader classLoader) {
        Map<String, List<XmlBindings>> bindings = new HashMap<String, List<XmlBindings>>();
        Object value = null;
        if (properties != null) {
            if ((value = properties.get(JAXBContextProperties.OXM_METADATA_SOURCE)) == null) {
                // try looking up the 'old' metadata source key
                value = properties.get(ECLIPSELINK_OXM_XML_KEY);
            }
        }
        if (value != null) {
            // handle Map<String, Object>
            if (value instanceof Map) {
                Map<String, Object> metadataFiles = null;
                try {
                    metadataFiles = (Map<String, Object>) value;
                } catch (ClassCastException x) {
                    throw org.eclipse.persistence.exceptions.JAXBException.incorrectValueParameterTypeForOxmXmlKey();
                }
                for(Entry<String, Object> entry : metadataFiles.entrySet()) {
                    String key = null;
                    List<XmlBindings> xmlBindings = new ArrayList<XmlBindings>();
                    try {
                        key = entry.getKey();
                        if (key == null) {
                            throw org.eclipse.persistence.exceptions.JAXBException.nullMapKey();
                        }
                    } catch (ClassCastException cce) {
                        throw org.eclipse.persistence.exceptions.JAXBException.incorrectKeyParameterType();
                    }
                    Object metadataSource = entry.getValue();
                    if (metadataSource == null) {
                        throw org.eclipse.persistence.exceptions.JAXBException.nullMetadataSource(key);
                    }
                    if(metadataSource instanceof List) {
                        for(Object next: (List)metadataSource) {
                            XmlBindings binding = getXmlBindings(next, classLoader, properties);
                            if(binding != null) {
                                xmlBindings.add(binding);
                            }
                        }
                    } else {
                        XmlBindings binding = getXmlBindings(metadataSource, classLoader, properties);
                        if(binding != null) {
                            xmlBindings.add(binding);
                        }
                    }
                    if (xmlBindings != null) {
                        bindings.put(key, xmlBindings);
                    }
                }
                // handle List<Object>
            } else if (value instanceof List) {
                for (Object metadataSource : (List) value) {
                    if (metadataSource == null) {
                        throw org.eclipse.persistence.exceptions.JAXBException.nullMetadataSource();
                    }
                    bindings = processBindingFile(bindings, metadataSource, classLoader, properties);
                }
            // handle Object
            } else {
                bindings = processBindingFile(bindings, value, classLoader, properties);
            }
        }
        Map<String, XmlBindings> mergedBindings = new HashMap<String, XmlBindings>(bindings.size());
        for(Entry<String, List<XmlBindings>> next:bindings.entrySet()) {
            mergedBindings.put(next.getKey(), XMLProcessor.mergeXmlBindings(next.getValue()));
        }
        return mergedBindings;
    }

    /**
     * Processing a bindings file and add it to a given Map of package name to binding
     * files.
     *
     * @param originalBindings Map of bindings to be updated
     * @param bindingHandle handle to bindings file
     */
    private static Map<String, List<XmlBindings>> processBindingFile(Map<String, List<XmlBindings>> originalBindings, Object bindingHandle, ClassLoader classLoader, Map<String, Object> properties) {
        XmlBindings binding = getXmlBindings(bindingHandle, classLoader, properties);
        if (binding != null) {
            String key = binding.getPackageName();
            if (key.equals(XMLProcessor.DEFAULT)) {
                throw org.eclipse.persistence.exceptions.JAXBException.packageNotSetForBindingException();
            }
            List<XmlBindings> existingBindings = originalBindings.get(key);
            if(existingBindings != null) {
                existingBindings.add(binding);
            } else {
                existingBindings = new ArrayList<XmlBindings>();
                existingBindings.add(binding);
                originalBindings.put(key, existingBindings);
            }
        }
        return originalBindings;
    }

    /**
     * Convenience method for creating an XmlBindings object based on a given Object. The method
     * will load the eclipselink metadata model and unmarshal the Object. This assumes that the
     * Object represents the eclipselink-oxm.xml metadata file to be unmarshalled.
     *
     * @param metadata assumed to be one of:  File, InputSource, InputStream, Reader, Source
     */
    private static XmlBindings getXmlBindings(Object metadata, ClassLoader classLoader, Map<String, Object> properties) {
    JAXBContext jaxbContext = CompilerHelper.getXmlBindingsModelContext();
        InputStream openedStream = null;

    try {
            Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
            unmarshaller.setProperty(UnmarshallerProperties.MEDIA_TYPE, MediaType.APPLICATION_XML);
            unmarshaller.setProperty(UnmarshallerProperties.AUTO_DETECT_MEDIA_TYPE, true);
            unmarshaller.setProperty(UnmarshallerProperties.JSON_INCLUDE_ROOT, false);
            unmarshaller.setEventHandler(new DefaultValidationEventHandler());
            if (metadata instanceof MetadataSource){
                return ((MetadataSource)metadata).getXmlBindings(properties, classLoader);
            }
            JAXBElement<XmlBindings> bindingsJaxbElement = null;
            if (metadata instanceof XMLEventReader) {
                bindingsJaxbElement=  unmarshaller.unmarshal((XMLEventReader) metadata, XmlBindings.class);
            } else if (metadata instanceof XMLStreamReader) {
                bindingsJaxbElement =  unmarshaller.unmarshal((XMLStreamReader) metadata, XmlBindings.class);
            } else {
                Source source = null;
                if(metadata instanceof File){
                    source = new StreamSource(new FileInputStream((File) metadata));
                } else if(metadata instanceof InputSource){
                    if(((InputSource)metadata).getByteStream() != null){
                        source = new StreamSource(((InputSource) metadata).getByteStream());
                    }else if(((InputSource)metadata).getCharacterStream() != null){
                        source = new StreamSource(((InputSource) metadata).getCharacterStream());
                    }
                }else if(metadata instanceof InputStream){
                    source = new StreamSource((InputStream) metadata);
                } else if (metadata instanceof Node) {
                    source = new DOMSource((Node) metadata);
                } else if(metadata instanceof Reader){
                    source = new StreamSource((Reader) metadata);
                } else if(metadata instanceof Source){
                    source = (Source)metadata;
                } else if (metadata instanceof URL) {
                    openedStream = ((URL) metadata).openStream();
                    source = new StreamSource(openedStream);
                } else if (metadata instanceof String) {
                    StreamSource streamSource = new StreamSource((String)metadata);
                    try{
                           bindingsJaxbElement = unmarshaller.unmarshal(streamSource, XmlBindings.class);
                    }catch(JAXBException e){
                        openedStream = classLoader.getResourceAsStream((String)metadata);
                        if(openedStream != null){
                            bindingsJaxbElement = unmarshaller.unmarshal(new StreamSource(openedStream), XmlBindings.class);
                        }else{
                            throw org.eclipse.persistence.exceptions.JAXBException.couldNotUnmarshalMetadata(e);
                        }
                    }
                } else{
                    throw org.eclipse.persistence.exceptions.JAXBException.incorrectValueParameterTypeForOxmXmlKey();
                }
                if(bindingsJaxbElement == null){
                    if(source == null){
                        throw org.eclipse.persistence.exceptions.JAXBException.incorrectValueParameterTypeForOxmXmlKey();
                    }else{
                        bindingsJaxbElement = unmarshaller.unmarshal(source, XmlBindings.class);
                    }
                }
            }
            if(bindingsJaxbElement != null){
                return bindingsJaxbElement.getValue();
            }
            throw org.eclipse.persistence.exceptions.JAXBException.incorrectValueParameterTypeForOxmXmlKey();
        }catch(jakarta.xml.bind.JAXBException ex){
            throw org.eclipse.persistence.exceptions.JAXBException.couldNotUnmarshalMetadata(ex);
        }catch(IOException ioException){
             throw org.eclipse.persistence.exceptions.JAXBException.couldNotUnmarshalMetadata(ioException);
        }finally{
            if(openedStream != null){
                try {
                    openedStream.close();
                } catch (IOException e) {
                    throw org.eclipse.persistence.exceptions.JAXBException.couldNotUnmarshalMetadata(e);
                }
            }
        }
    }
}
