/*
 * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
 * Copyright (c) 1998, 2018 IBM Corporation. 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:
//     dclarke, mnorman - Dynamic Persistence
//       http://wiki.eclipse.org/EclipseLink/Development/Dynamic
//       (https://bugs.eclipse.org/bugs/show_bug.cgi?id=200045)
//     08/29/2016 Jody Grassel
//       - 500441: Eclipselink core has System.getProperty() calls that are not potentially executed under doPriv()
//
package org.eclipse.persistence.dynamic;

//javase imports
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.persistence.config.SystemProperties;
import org.eclipse.persistence.exceptions.DynamicException;
import org.eclipse.persistence.internal.helper.ConversionManager;
import org.eclipse.persistence.internal.helper.Helper;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.sessions.Session;

/**
 * This custom ClassLoader provides support for dynamically generating classes
 * within an EclipseLink application using byte codes created using a
 * {@link DynamicClassWriter}. A DynamicClassLoader requires a parent or
 * delegate class-loader which is provided to the constructor. This delegate
 * class loader handles the lookup and storage of all created classes.
 *
 * @author dclarke, mnorman
 * @since EclipseLink 1.2
 */
public class DynamicClassLoader extends ClassLoader {

    /**
     * Map of {@link DynamicClassWriter} used to dynamically create a class in
     * the {@link #findClass(String)} call. The application must register
     * classes using addClass or createDynameClass prior to the
     * {@link #findClass(String)} being invoked.
     * <p>
     * The map of writers is maintained for the life of this DynamicClassLoader
     * instance to ensure additional requests to create dynamic classes of the
     * same name are properly verified. Duplicate requests for dynamic classes
     * of the same name, same writer type, and the same parent class are
     * permitted but different parent classes or different writer types are not.
     */
    protected Map<String, EclipseLinkClassWriter> classWriters = new HashMap<>();
    protected Map<String, EnumInfo> enumInfoRegistry = new HashMap<>();

    /**
     * Default writer to use if one is not specified.
     */
    public DynamicClassWriter defaultWriter = new DynamicClassWriter();

    /**
     * Create a DynamicClassLoader providing the delegate loader and leaving the
     * defaultWriter as {@link DynamicClassWriter}
     */
    public DynamicClassLoader(ClassLoader delegate) {
        super(delegate);
    }

    /**
     * Create a DynamicClassLoader providing the delegate loader and a default
     * {@link DynamicClassWriter}.
     */
    public DynamicClassLoader(ClassLoader delegate, DynamicClassWriter writer) {
        this(delegate);
        this.defaultWriter = writer;
    }

    public DynamicClassWriter getDefaultWriter() {
        return this.defaultWriter;
    }

    protected Map<String, EclipseLinkClassWriter> getClassWriters() {
        return this.classWriters;
    }

    public EclipseLinkClassWriter getClassWriter(String className) {
        return getClassWriters().get(className);
    }

    public void addEnum(String className, Object... literalLabels) {
        EnumInfo enumInfo = enumInfoRegistry.get(className);
        if (enumInfo == null) {
            enumInfo = new EnumInfo(className);
            enumInfoRegistry.put(className, enumInfo);
        }
        if (literalLabels != null) {
            for (Object literalLabel : literalLabels) {
                if (literalLabel != null) {
                    enumInfo.addLiteralLabel(literalLabel.toString());
                }
            }
        }
        addClass(className);
    }

    /**
     * Register a class to be dynamically created using the default
     * {@link DynamicClassWriter}.
     *
     * @see #addClass(String, EclipseLinkClassWriter)
     */
    public void addClass(String className) {
        addClass(className, getDefaultWriter());
    }

    /**
     * Register a class to be dynamically created using a copy of default
     * {@link DynamicClassWriter} but specifying a different parent class.
     *
     * @see #addClass(String, EclipseLinkClassWriter)
     */
    public void addClass(String className, Class<?> parentClass) {
        addClass(className, getDefaultWriter().createCopy(parentClass));
    }

    /**
     * Register a class to be dynamically created using the provided
     * {@link DynamicClassWriter}. The registered writer is used when the
     * {@link #findClass(String)} method is called back on this loader from the
     * {@link #loadClass(String)} call.
     * <p>
     * If a duplicate request is made for the same className and the writers are
     * not compatible a {@link DynamicException} will be thrown. If the
     * duplicate request contains a compatible writer then the second request is
     * ignored as the class may already have been generated.
     *
     * @see #findClass(String)
     */
    public void addClass(String className, EclipseLinkClassWriter writer) throws DynamicException {
        EclipseLinkClassWriter existingWriter = getClassWriter(className);

        // Verify that the existing writer is compatible with the requested
        if (existingWriter != null) {
            if (!existingWriter.isCompatible(writer)) {
                throw DynamicException.incompatibleDuplicateWriters(className, existingWriter, writer);
            }
        } else {
            getClassWriters().put(className, writer == null ? getDefaultWriter() : writer);
        }
    }

    /**
     * Create a dynamic class registering a writer and then forcing the provided
     * class name to be loaded.
     *
     */
    public Class<?> createDynamicClass(String className, DynamicClassWriter writer) {
        addClass(className, writer);
        Class<?> newDynamicClass = null;
        try {
            newDynamicClass = loadClass(className);
        }
        catch (ClassNotFoundException cnfe) {
            throw new IllegalArgumentException("DyanmicClassLoader: could not create class " + className);
        }
        return checkAssignable(newDynamicClass);
    }

    protected Class<?> checkAssignable(Class<?> clz) {
        EclipseLinkClassWriter assignedClassWriter = getClassWriters().get(clz.getName());
        if ((assignedClassWriter.getParentClass() == null && !assignedClassWriter.getParentClassName().equals(clz.getName())) || !assignedClassWriter.getParentClass().isAssignableFrom(clz)) {
            throw new IllegalArgumentException("DynamicClassLoader: " + clz.getName() + " not compatible with parent class " + assignedClassWriter.getParentClass().getName());
        }
        return clz;
    }

    /**
     * Create a new dynamic entity type for the specified name assuming the use
     * of the default writer and its default parent class.
     *
     * @see #createDynamicClass(String, DynamicClassWriter)
     */
    public Class<?> createDynamicClass(String className) {
        return createDynamicClass(className, getDefaultWriter());
    }

    /**
     * Create a new dynamic entity type for the specified name with the
     * specified parent class.
     *
     * @see #createDynamicClass(String, DynamicClassWriter)
     */
    public Class<?> createDynamicClass(String className, Class<?> parentClass) {
        return createDynamicClass(className, new DynamicClassWriter(parentClass));
    }

    /**
     * Create an adapter for given {@code className}
     *
     */
    public void createDynamicAdapter(String className) {
        // default no-op
    }

    /**
     * Create a collection adapter for given {@code className}
     *
     */
    public void createDynamicCollectionAdapter(String className) {
        // default no-op
    }

    /**
     * Create a reference for given {@code className}
     *
     */
    public void createDynamicReferenceAdapter(String className) {
        // default no-op
    }

    /**
     * Create a new dynamic class if a ClassWriter is registered for the
     * provided className. This code is single threaded to ensure only one class
     * is created for a given name and that the ClassWriter is removed
     * afterwards.
     */
    @Override
    protected Class<?> findClass(String className) throws ClassNotFoundException {
        EclipseLinkClassWriter writer = getClassWriter(className);

        if (writer != null) {
            try {
                byte[] bytes = writer.writeClass(this, className);
                if (bytes != null) {
                    String outputPath = PrivilegedAccessHelper.getSystemProperty(SystemProperties.WEAVING_OUTPUT_PATH, "");

                    if (!outputPath.equals("")) {
                        Helper.outputClassFile(className, bytes, outputPath);
                    }
                }
                return defineDynamicClass(className, bytes);
            } catch (ClassFormatError cfe) {
                throw new ClassNotFoundException(className, cfe);
            } catch (ClassCircularityError cce) {
                throw new ClassNotFoundException(className, cce);
            }
        }

        return super.findClass(className);
    }

    /**
     * Converts an array of bytes into an instance of class <code>Class</code>.
     * Before the <code>Class</code> can be used it must be resolved.
     *
     */
    protected Class<?> defineDynamicClass(String name, byte[] b)  {
        return defineClass(name, b, 0, b.length);
    }

    /**
     * Lookup the DynamicConversionManager for the given session. If the
     * existing ConversionManager is not an instance of DynamicConversionManager
     * then create a new one and replace the existing one.
     *
     */
    public static DynamicClassLoader lookup(Session session) {
        ConversionManager cm = null;

        if (session == null) {
            cm = ConversionManager.getDefaultManager();
        } else {
            cm = session.getPlatform().getConversionManager();
        }

        if (cm.getLoader() instanceof DynamicClassLoader) {
            return (DynamicClassLoader) cm.getLoader();
        }

        DynamicClassLoader dcl = new DynamicClassLoader(cm.getLoader());
        cm.setLoader(dcl);

        if (session == null) {
            ConversionManager.setDefaultLoader(dcl);
        }

        return dcl;
    }

    public static class EnumInfo {
        String className;
        List<String> literalLabels = new ArrayList<>();

        public EnumInfo(String className) {
            this.className = className;
        }

        public String getClassName() {
            return className;
        }

        public String[] getLiteralLabels() {
            return literalLabels.toArray(new String[literalLabels.size()]);
        }

        public void addLiteralLabel(String literalLabel) {
            if (!literalLabels.contains(literalLabel) && literalLabel != null) {
                literalLabels.add(literalLabel);
            }
        }
    }

}
