/*
 * Copyright (c) 2011, 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:
//     Rick Barkhouse - 2.1 - initial implementation
package org.eclipse.persistence.jaxb.dynamic;

import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

import javax.xml.transform.stream.StreamSource;

import jakarta.xml.bind.JAXBException;

import org.eclipse.persistence.core.sessions.CoreProject;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.dynamic.DynamicClassLoader;
import org.eclipse.persistence.dynamic.DynamicEntity;
import org.eclipse.persistence.dynamic.DynamicHelper;
import org.eclipse.persistence.dynamic.DynamicType;
import org.eclipse.persistence.dynamic.DynamicTypeBuilder;
import org.eclipse.persistence.internal.descriptors.InstantiationPolicy;
import org.eclipse.persistence.internal.jaxb.JaxbClassLoader;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.jaxb.compiler.Generator;
import org.eclipse.persistence.jaxb.dynamic.metadata.Metadata;
import org.eclipse.persistence.jaxb.dynamic.metadata.OXMMetadata;
import org.eclipse.persistence.oxm.XMLContext;
import org.eclipse.persistence.sessions.DatabaseSession;
import org.eclipse.persistence.sessions.Project;
import org.eclipse.persistence.sessions.Session;
import org.eclipse.persistence.sessions.factories.SessionManager;
import org.eclipse.persistence.sessions.factories.XMLSessionConfigLoader;
import org.w3c.dom.Node;
import org.xml.sax.EntityResolver;

/**
 * <p>
 * A specialized <code>JAXBContext</code> for marshalling and unmarshalling <code>DynamicEntities</code>.
 * </p>
 *
 * <p>
 * <code>DynamicJAXBContext</code> also provides methods to:
 * </p>
 * <ul>
 *      <li>get the <code>DynamicType</code> associated with a given Java name
 *      <li>get the <code>DynamicType</code> associated with a given XML name
 *      <li>create a new <code>DynamicEntity</code> given the Java name of its <code>DynamicType</code>
 *      <li>create a new <code>DynamicEntity</code> given the XML name of its <code>DynamicType</code>
 * </ul>
 *
 * <p>
 * New instances of <code>DynamicJAXBContext</code> must be created with <code>DynamicJAXBContextFactory</code>.
 * </p>
 *
 * @see jakarta.xml.bind.JAXBContext
 * @see org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContextFactory
 * @see org.eclipse.persistence.dynamic.DynamicEntity
 * @see org.eclipse.persistence.dynamic.DynamicType
 *
 * @author rbarkhouse
 * @since EclipseLink 2.1
 */

public class DynamicJAXBContext extends org.eclipse.persistence.jaxb.JAXBContext {

    DynamicJAXBContext(JAXBContextInput input) throws JAXBException {
        super(input);
    }

    public DynamicClassLoader getDynamicClassLoader() {
        return ((DynamicJAXBContextInput) contextInput).getClassLoader();
    }

    private ArrayList<DynamicHelper> getHelpers() {
        return ((DynamicJAXBContextState) contextState).getHelpers();
    }

    /**
     * Obtain a reference to the <code>DynamicType</code> object for a given Java name.  If one has
     * not been generated, this method will return <code>null</code>.
     *
     * @param javaName
     *      A Java class name, used to look up its <code>DynamicType</code>.
     *
     * @return
     *      The <code>DynamicType</code> for this Java class name.
     */
    public DynamicType getDynamicType(String javaName) {
        for (DynamicHelper helper : getHelpers()) {
            DynamicType type = helper.getType(javaName);
            if (type != null) {
                return type;
            }
        }
        return null;
    }

    /**
     * Create a new instance of <code>DynamicEntity</code> for a given Java name.  If a
     * <code>DynamicType</code> for this Java class name has not been generated, this
     * method will return <code>null</code>.
     *
     * @param javaName
     *      The Java class name to create a new <code>DynamicEntity</code> for.
     *
     * @return
     *      A new <code>DynamicEntity</code> for this Java class name.
     */
    public DynamicEntity newDynamicEntity(String javaName) throws IllegalArgumentException {
        IllegalArgumentException ex = null;
        for (DynamicHelper helper : getHelpers()) {
            try {
                return helper.newDynamicEntity(javaName);
            } catch (IllegalArgumentException e) {
                ex = e;
            }
        }
        throw ex;
    }

    /**
     * Create a new instance of <code>DynamicEntity</code> for a given <code>DynamicType</code>.
     *
     * @param dynamicType
     *      The <code>DynamicType</code> to create a new <code>DynamicEntity</code> for.
     *
     * @return
     *      A new <code>DynamicEntity</code> for this <code>DynamicType</code>.
     */
    public DynamicEntity newDynamicEntity(DynamicType dynamicType) {
        return dynamicType.newDynamicEntity();
    }

    /**
     * Returns the constant named <code>constantName</code> from the enum class specified by <code>enumName</code>.
     *
     * @param enumName
     *      Java class name of an enum.
     * @param constantName
     *      Name of the constant to get from the specified enum.
     *
     * @return
     *      An <code>Object</code>, the constant from the specified enum.
     */
    public Object getEnumConstant(String enumName, String constantName) throws ClassNotFoundException, JAXBException {
        Object valueToReturn = null;

        Class<?> enumClass = getDynamicClassLoader().loadClass(enumName);
        Object[] enumConstants = enumClass.getEnumConstants();
        for (Object enumConstant : enumConstants) {
            if (enumConstant.toString().equals(constantName)) {
                valueToReturn = enumConstant;
            }
        }

        if (valueToReturn != null) {
            return valueToReturn;
        } else {
            throw new JAXBException(org.eclipse.persistence.exceptions.JAXBException.enumConstantNotFound(enumName + "." + constantName));
        }
    }

    // ========================================================================

    static class DynamicJAXBContextState extends JAXBContextState {
        private ArrayList<DynamicHelper> helpers;
        private DynamicClassLoader dClassLoader;

        public DynamicJAXBContextState(DynamicClassLoader loader) {
            super();
            helpers = new ArrayList<DynamicHelper>();
        }

        public DynamicJAXBContextState(XMLContext ctx) {
            super(ctx);
        }

        public ArrayList<DynamicHelper> getHelpers() {
            return helpers;
        }

        public void setHelpers(ArrayList<DynamicHelper> helpers) {
            this.helpers = helpers;
        }

        public DynamicClassLoader getDynamicClassLoader() {
            return dClassLoader;
        }

        public void setDynamicClassLoader(DynamicClassLoader dClassLoader) {
            this.dClassLoader = dClassLoader;
        }
    }

    // ========================================================================

    static abstract class DynamicJAXBContextInput extends org.eclipse.persistence.jaxb.JAXBContext.JAXBContextInput {

        public DynamicJAXBContextInput(Map properties, ClassLoader classLoader) {
            super(properties, classLoader);
            if (classLoader == null) {
                classLoader = PrivilegedAccessHelper.callDoPrivileged(
                        () -> PrivilegedAccessHelper.getContextClassLoader(Thread.currentThread())
                );
            }
            final DynamicClassLoader dClassLoader;
            if (classLoader instanceof DynamicClassLoader) {
               dClassLoader = (DynamicClassLoader) classLoader;
            } else {
                final ClassLoader parent = classLoader;
                dClassLoader = PrivilegedAccessHelper.callDoPrivileged(
                        () -> new DynamicClassLoader(new JaxbClassLoader(parent))
                );
            }
            this.classLoader = dClassLoader;
        }

        public DynamicClassLoader getClassLoader() {
            return (DynamicClassLoader) this.classLoader;
        }

    }

    static class MetadataContextInput extends DynamicJAXBContextInput {
        public MetadataContextInput(Map properties, ClassLoader classLoader) {
            super(properties, classLoader);
        }

        @Override
        protected JAXBContextState createContextState() throws JAXBException {
            DynamicJAXBContextState state = new DynamicJAXBContextState((DynamicClassLoader) classLoader);

            Metadata oxmMetadata = new OXMMetadata((DynamicClassLoader) classLoader, properties);

            Generator g = new Generator(oxmMetadata.getJavaModelInput(), oxmMetadata.getBindings(), classLoader, null, false);

            CoreProject p = null;
            Project dp = null;
            try {
                p = g.generateProject();
                // Clear out InstantiationPolicy because it refers to ObjectFactory, which we won't be using
                List<ClassDescriptor> descriptors = p.getOrderedDescriptors();
                for (ClassDescriptor classDescriptor : descriptors) {
                    try {
                        if(null == classDescriptor.getJavaClass()) {
                            classDescriptor.setJavaClass(classLoader.getParent().loadClass(classDescriptor.getJavaClassName()));
                        }
                    } catch(ClassNotFoundException e) {
                        classDescriptor.setInstantiationPolicy(new InstantiationPolicy());
                    }
                }
                dp = DynamicTypeBuilder.loadDynamicProject((Project)p, null, (DynamicClassLoader) classLoader);
            } catch (Exception e) {
                throw new JAXBException(org.eclipse.persistence.exceptions.JAXBException.errorCreatingDynamicJAXBContext(e));
            }

            XMLContext ctx = new XMLContext(dp, classLoader, sessionEventListeners());
            state.setXMLContext(ctx);

            List<Session> sessions = ctx.getSessions();
            for (Object session : sessions) {
                state.getHelpers().add(new DynamicHelper((DatabaseSession) session));
            }

            return state;
        }
    }

    static class SchemaContextInput extends DynamicJAXBContextInput {
        private Object schema = null;
        private EntityResolver entityResolver;

        public static final String SCHEMAMETADATA_CLASS_NAME = "org.eclipse.persistence.jaxb.dynamic.metadata.SchemaMetadata";

        public SchemaContextInput(Object schema, EntityResolver resolver, Map properties, ClassLoader classLoader) {
            super(properties, classLoader);
            this.schema = schema;
            this.entityResolver = resolver;
        }

        @Override
        protected JAXBContextState createContextState() throws JAXBException {
            DynamicJAXBContextState state = new DynamicJAXBContextState((DynamicClassLoader) classLoader);

            Metadata schemaMetadata = null;
            Object constructorArg;
            if (schema instanceof Node) {
                constructorArg = schema;
            } else if (schema instanceof InputStream) {
                constructorArg = new StreamSource((InputStream) schema);
            } else {
                constructorArg = schema;
            }

            try {
                Class<?> schemaMetadataClass = PrivilegedAccessHelper.getClassForName(SCHEMAMETADATA_CLASS_NAME);
                Class<?>[] constructorClassArgs = {DynamicClassLoader.class, Map.class, constructorArg.getClass(), EntityResolver.class};
                Constructor<?> constructor = PrivilegedAccessHelper.getConstructorFor(schemaMetadataClass, constructorClassArgs, true);
                Object[] contructorObjectArgs = {classLoader, properties, constructorArg, entityResolver};
                schemaMetadata = (Metadata) PrivilegedAccessHelper.invokeConstructor(constructor, contructorObjectArgs);
            } catch (InvocationTargetException e) {
                Throwable cause = e.getCause();
                if (cause instanceof JAXBException) {
                    throw (JAXBException) cause;
                } else if (cause instanceof org.eclipse.persistence.exceptions.JAXBException) {
                    throw (org.eclipse.persistence.exceptions.JAXBException) cause;
                } else {
                    throw new JAXBException(e);
                }
            } catch (org.eclipse.persistence.exceptions.JAXBException e) {
                throw e;
            } catch (Exception e) {
                throw new JAXBException(e);
            }

            Generator g = new Generator(schemaMetadata.getJavaModelInput(), schemaMetadata.getBindings(), classLoader, null, false);

            Project p = null;
            Project dp = null;
            try {
                p = (Project) g.generateProject();
                // Clear out InstantiationPolicy because it refers to ObjectFactory, which we won't be using
                List<ClassDescriptor> descriptors = p.getOrderedDescriptors();
                for (ClassDescriptor classDescriptor : descriptors) {
                    classDescriptor.setInstantiationPolicy(new InstantiationPolicy());
                }
                dp = DynamicTypeBuilder.loadDynamicProject(p, null, (DynamicClassLoader) classLoader);
            } catch (Exception e) {
                throw new JAXBException(org.eclipse.persistence.exceptions.JAXBException.errorCreatingDynamicJAXBContext(e));
            }

            XMLContext ctx = new XMLContext(dp, classLoader, sessionEventListeners());
            state.setXMLContext(ctx);

            List<Session> sessions = ctx.getSessions();
            for (Object session : sessions) {
                state.getHelpers().add(new DynamicHelper((DatabaseSession) session));
            }

            return state;
        }
    }

    static class SessionsXmlContextInput extends DynamicJAXBContextInput {
        private String sessions;

        public SessionsXmlContextInput(String sessionNames, Map properties, ClassLoader classLoader) {
            super(properties, classLoader);
            this.sessions = sessionNames;
        }

        @Override
        protected JAXBContextState createContextState() throws JAXBException {
            DynamicJAXBContextState state = new DynamicJAXBContextState((DynamicClassLoader) classLoader);

            StringTokenizer st = new StringTokenizer(sessions, ":");
            ArrayList<Project> dynamicProjects = new ArrayList<Project>(st.countTokens());

            XMLSessionConfigLoader loader = new XMLSessionConfigLoader();

            while (st.hasMoreTokens()) {
                DatabaseSession dbSession =
                    (DatabaseSession) SessionManager.getManager().getSession(loader, st.nextToken(), classLoader, false, true);
                Project p = DynamicTypeBuilder.loadDynamicProject(dbSession.getProject(), null, (DynamicClassLoader) classLoader);
                dynamicProjects.add(p);
            }

            XMLContext xmlContext = new XMLContext(dynamicProjects);
            state.setXMLContext(xmlContext);

            List<Session> sessions = xmlContext.getSessions();
            for (Object session : sessions) {
                state.getHelpers().add(new DynamicHelper((DatabaseSession) session));
            }

            return state;
        }
    }

}
