/*
 * 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
//     19/04/2014-2.6 Lukas Jungmann
//       - 429992: JavaSE 8/ASM 5.0.1 support (EclipseLink silently ignores Entity classes with lambda expressions)
package org.eclipse.persistence.internal.jpa.weaving;

// J2SE imports
import java.lang.instrument.IllegalClassFormatException;
import java.security.ProtectionDomain;
import java.util.Map;

import jakarta.persistence.spi.ClassTransformer;

import org.eclipse.persistence.config.SystemProperties;
import org.eclipse.persistence.internal.helper.Helper;
import org.eclipse.persistence.internal.libraries.asm.ClassReader;
import org.eclipse.persistence.internal.libraries.asm.ClassVisitor;
import org.eclipse.persistence.internal.libraries.asm.ClassWriter;
import org.eclipse.persistence.internal.libraries.asm.EclipseLinkClassReader;
import org.eclipse.persistence.internal.libraries.asm.commons.SerialVersionUIDAdder;
import org.eclipse.persistence.internal.localization.ExceptionLocalization;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.logging.AbstractSessionLog;
import org.eclipse.persistence.logging.SessionLog;
import org.eclipse.persistence.logging.SessionLogEntry;

/**
 * INTERNAL:
 * This class performs dynamic byte code weaving: for each attribute
 * mapped with One To One mapping with Basic Indirection it substitutes the
 * original attribute's type for ValueHolderInterface.
 */
public class PersistenceWeaver implements ClassTransformer {

    /** Class name in JVM '/' format to {@link ClassDetails} map. */
    protected Map<String, ClassDetails> classDetailsMap;

    /**
     * INTERNAL:
     * Creates an instance of dynamic byte code weaver.
     * @param classDetailsMap Class name to {@link ClassDetails} map.
     * @since 2.7
     */
    public PersistenceWeaver(final Map<String, ClassDetails> classDetailsMap) {
        this.classDetailsMap = classDetailsMap;
    }

    /**
     * INTERNAL:
     * Allow the weaver to be clear to release its referenced memory.
     * This is required because the class loader reference to the transformer will never gc.
     */
    public void clear() {
        this.classDetailsMap = null;
    }

    /**
     * INTERNAL:
     * Get Class name in JVM '/' format to {@link ClassDetails} map.
     * @return Class name in JVM '/' format to {@link ClassDetails} map.
     */
    public Map<String, ClassDetails> getClassDetailsMap() {
        return classDetailsMap;
    }

    /**
     * INTERNAL:
     * Perform dynamic byte code weaving of class.
     * @param loader              The defining loader of the class to be transformed, may be {@code null}
     *                            if the bootstrap loader.
     * @param className           The name of the class in the internal form of fully qualified class and interface
     *                            names.
     * @param classBeingRedefined If this is a redefine, the class being redefined, otherwise {@code null}.
     * @param protectionDomain    The protection domain of the class being defined or redefined.
     * @param classfileBuffer     The input byte buffer in class file format (must not be modified).
     * @return  A well-formed class file buffer (the result of the transform), or {@code null} if no transform
     *          is performed.
     */
    @Override
    public byte[] transform(final ClassLoader loader, final String className,
            final Class<?> classBeingRedefined, final ProtectionDomain protectionDomain,
            final byte[] classfileBuffer) throws IllegalClassFormatException {
        final SessionLog log = AbstractSessionLog.getLog();
        // PERF: Is finest logging on weaving turned on?
        final boolean shouldLogFinest = log.shouldLog(SessionLog.FINEST, SessionLog.WEAVER);
        final Map<String, ClassDetails> classDetailsMap = this.classDetailsMap;
        // Check if cleared already.
        if (classDetailsMap == null) {
            return null;
        }
        try {
            /*
             * The ClassFileTransformer callback - when called by the JVM's
             * Instrumentation implementation - is invoked for every class loaded.
             * Thus, we must check the classDetailsMap to see if we are 'interested'
             * in the class.
             */
            final ClassDetails classDetails = classDetailsMap.get(Helper.toSlashedClassName(className));

            if (classDetails != null) {
                if (shouldLogFinest) {
                    log.log(SessionLog.FINEST, SessionLog.WEAVER, "begin_weaving_class", className);
                }
                ClassReader classReader = null;
                try {
                    classReader = new ClassReader(classfileBuffer);
                } catch (IllegalArgumentException iae) {
                    // class was probably compiled with some newer than officially supported and tested JDK
                    // in such case log a warning and try to re-read the class without class version check
                    if (log.shouldLog(SessionLog.FINE, SessionLog.WEAVER)) {
                        SessionLogEntry entry = new SessionLogEntry(null, SessionLog.FINE, SessionLog.WEAVER, iae);
                        entry.setMessage(ExceptionLocalization.buildMessage("unsupported_classfile_version", new Object[] { className }));
                        log.log(entry);
                    }
                    classReader = new EclipseLinkClassReader(classfileBuffer);
                }
                final String reflectiveIntrospectionProperty =
                        PrivilegedAccessHelper.getSystemProperty(SystemProperties.WEAVING_REFLECTIVE_INTROSPECTION);
                final ClassWriter classWriter = reflectiveIntrospectionProperty != null
                        ? new ClassWriter(ClassWriter.COMPUTE_FRAMES)
                        : new ComputeClassWriter(loader, ClassWriter.COMPUTE_FRAMES);
                final ClassWeaver classWeaver = new ClassWeaver(classWriter, classDetails);
                final ClassVisitor sv = new SerialVersionUIDAdder(classWeaver);
                classReader.accept(sv, 0);
                if (classWeaver.alreadyWeaved) {
                    if (shouldLogFinest) {
                        log.log(SessionLog.FINEST, SessionLog.WEAVER, "end_weaving_class", className);
                    }
                    return null;
                }
                if (classWeaver.weaved) {
                    final byte[] bytes = classWriter.toByteArray();
                    final String outputPath =
                            PrivilegedAccessHelper.getSystemProperty(SystemProperties.WEAVING_OUTPUT_PATH, "");

                    if (!outputPath.equals("")) {
                        Helper.outputClassFile(className, bytes, outputPath);
                    }
                    // PERF: Don't execute this set of if statements with logging turned off.
                    if (shouldLogFinest) {
                        if (classWeaver.weavedPersistenceEntity) {
                            log.log(SessionLog.FINEST, SessionLog.WEAVER, "weaved_persistenceentity", className);
                        }
                        if (classWeaver.weavedChangeTracker) {
                            log.log(SessionLog.FINEST, SessionLog.WEAVER, "weaved_changetracker", className);
                        }
                        if (classWeaver.weavedLazy) {
                            log.log(SessionLog.FINEST, SessionLog.WEAVER, "weaved_lazy", className);
                        }
                        if (classWeaver.weavedFetchGroups) {
                            log.log(SessionLog.FINEST, SessionLog.WEAVER, "weaved_fetchgroups", className);
                        }
                        if (classWeaver.weavedRest) {
                            log.log(SessionLog.FINEST, SessionLog.WEAVER, "weaved_rest", className);
                        }
                        log.log(SessionLog.FINEST, SessionLog.WEAVER, "end_weaving_class", className);
                    }
                    return bytes;
                }
                if (shouldLogFinest) {
                    log.log(SessionLog.FINEST, SessionLog.WEAVER, "end_weaving_class", className);
                }
            } else {
                if (shouldLogFinest) {
                    log.log(SessionLog.FINEST, SessionLog.WEAVER, "transform_missing_class_details", className);
                }
            }
        } catch (Throwable exception) {
            if (log.shouldLog(SessionLog.WARNING, SessionLog.WEAVER)) {
                log.log(SessionLog.WARNING, SessionLog.WEAVER,
                        "exception_while_weaving", new Object[] {className, exception.getLocalizedMessage()});
                if (shouldLogFinest) {
                    log.logThrowable(SessionLog.FINEST, SessionLog.WEAVER, exception);
                }
            }
        }
        if (shouldLogFinest) {
            log.log(SessionLog.FINEST, SessionLog.WEAVER, "transform_existing_class_bytes", className);
        }
        // Returning null means 'use existing class bytes'.
        return null;
    }

    /**
     * INTERNAL:
     * Returns an unqualified class name from the specified class name.
     * @param name Class name with {@code '/'} as delimiter.
     * @return Unqualified class name.
     */
    protected static String getShortName(String name) {
        int pos  = name.lastIndexOf('/');
        if (pos >= 0) {
            name = name.substring(pos+1);
            if (name.endsWith(";")) {
                name = name.substring(0, name.length()-1);
            }
            return name;
        }
        return "";
    }

}
