/*
 * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
 * Copyright (c) 2021 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:
//     Oracle - initial API and implementation from Oracle TopLink
//     11/10/2011-2.4 Guy Pelletier
//       - 357474: Address primaryKey option from tenant discriminator column
//     11/29/2012-2.5 Guy Pelletier
//       - 395406: Fix nightly static weave test errors
package org.eclipse.persistence.internal.jpa.weaving;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.indirection.ValueHolderInterface;
import org.eclipse.persistence.internal.descriptors.VirtualAttributeMethodInfo;
import org.eclipse.persistence.internal.helper.Helper;
import org.eclipse.persistence.internal.indirection.BasicIndirectionPolicy;
import org.eclipse.persistence.internal.jpa.metadata.accessors.objects.MetadataClass;
import org.eclipse.persistence.internal.jpa.metadata.accessors.objects.MetadataField;
import org.eclipse.persistence.internal.jpa.metadata.accessors.objects.MetadataMethod;
import org.eclipse.persistence.internal.libraries.asm.Type;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.internal.weaving.PersistenceWeavedChangeTracking;
import org.eclipse.persistence.logging.SessionLog;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.mappings.ForeignReferenceMapping;
import org.eclipse.persistence.mappings.foundation.AbstractDirectMapping;
import org.eclipse.persistence.sessions.Project;
import org.eclipse.persistence.sessions.Session;

/**
 * This class creates a ClassFileTransformer that is used for dynamic bytecode
 * weaving. It is called by {@link org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl#predeploy}
 * <p>
 * <i>Note:</i> The Session's Project is is scanned to ensure that weaving is
 * supported and is <b>modified</b> to suit (set the {@link org.eclipse.persistence.descriptors.changetracking.ObjectChangePolicy}
 * for the Descriptor).
 */
public class TransformerFactory {

    public static final String WEAVER_DISABLE_CT_NOT_SUPPORTED = "weaver_change_tracking_disabled_not_supported";
    public static final String WEAVER_FOUND_USER_IMPL_CT = "weaver_user_impl_change_tracking";
    public static final String WEAVER_NULL_PROJECT = "weaver_null_project";
    public static final String WEAVER_DISABLE_BY_SYSPROP = "weaver_disable_by_system_property";
    public static final String WEAVER_CLASS_NOT_IN_PROJECT = "weaver_class_not_in_project";
    public static final String WEAVER_PROCESSING_CLASS = "weaver_processing_class";
    public static final String CANNOT_WEAVE_CHANGETRACKING = "cannot_weave_changetracking";
    public static final String CANNOT_WEAVE_VIRTUAL_ONE_TO_ONE = "cannot_weave_virtual_one_to_one";

    protected Session session;
    protected Collection<MetadataClass> entityClasses;
    protected Map<String, ClassDetails> classDetailsMap;
    protected ClassLoader classLoader;
    protected boolean weaveChangeTracking;
    protected boolean weaveLazy;
    protected boolean weaveFetchGroups;
    protected boolean weaveInternal;
    protected boolean weaveRest;
    protected boolean weaveMappedSuperClass;

    public static PersistenceWeaver createTransformerAndModifyProject(
            Session session, Collection<MetadataClass> entityClasses, ClassLoader classLoader,
            boolean weaveLazy, boolean weaveChangeTracking, boolean weaveFetchGroups,
            boolean weaveInternal, boolean weaveRest, boolean weaveMappedSuperClass) {
        if (session == null) {
            throw new IllegalArgumentException("Weaver session cannot be null");
        }
        if (session.getProject() == null) {
            ((AbstractSession)session).log(SessionLog.SEVERE, SessionLog.WEAVER, WEAVER_NULL_PROJECT, null);
            throw new IllegalArgumentException("Weaver session's project cannot be null");
        }
        TransformerFactory tf = new TransformerFactory(session, entityClasses, classLoader, weaveLazy, weaveChangeTracking, weaveFetchGroups, weaveInternal, weaveRest, weaveMappedSuperClass);
        tf.buildClassDetailsAndModifyProject();
        return tf.buildPersistenceWeaver();
    }

    public TransformerFactory(Session session, Collection<MetadataClass> entityClasses, ClassLoader classLoader,
            boolean weaveLazy, boolean weaveChangeTracking, boolean weaveFetchGroups,
            boolean weaveInternal, boolean weaveRest, boolean weaveMappedSuperClass) {
        this.session = session;
        this.entityClasses = entityClasses;
        this.classLoader = classLoader;
        this.classDetailsMap = new HashMap<String, ClassDetails>();
        this.weaveLazy = weaveLazy;
        this.weaveChangeTracking = weaveChangeTracking;
        this.weaveFetchGroups = weaveFetchGroups;
        this.weaveInternal = weaveInternal;
        this.weaveRest = weaveRest;
        this.weaveMappedSuperClass = weaveMappedSuperClass;
    }

    /**
     * INTERNAL:
     * Look higher in the hierarchy for the mappings listed in the unMappedAttribute list.
     *
     * We assume that if a mapping exists, the attribute must either be mapped from the owning
     * class or from a superclass.
     */
    public void addClassDetailsForMappedSuperClasses(MetadataClass clz, ClassDescriptor initialDescriptor, ClassDetails classDetails, Map<String, ClassDetails> classDetailsMap, List<DatabaseMapping> unMappedAttributes, boolean weaveChangeTracking){
        MetadataClass superClz = clz.getSuperclass();
        if (superClz == null || superClz.isObject()){
            return;
        }

        ClassDescriptor mappedSuperclassDescriptor = ((AbstractSession) session).getMappedSuperclass(superClz.getName());
        if (mappedSuperclassDescriptor == null) {
            ClassDescriptor descriptor = findDescriptor(session.getProject(), clz.getSuperclass().getName());
            if (descriptor != null) {
                return;
            }
        }

        // If the superclass declares more mappings than there are unmapped mappings still to process, this superclass has shadowed attributes
        if(mappedSuperclassDescriptor != null && unMappedAttributes.size() < mappedSuperclassDescriptor.getMappings().size()) {
            List<DatabaseMapping> hiddenMappings = new ArrayList<DatabaseMapping>();
            for(DatabaseMapping mapping : mappedSuperclassDescriptor.getMappings()) {
                boolean contains = false;
                String name = mapping.getAttributeName();
                for(DatabaseMapping newmapping : unMappedAttributes) {
                    if(name.equals(newmapping.getAttributeName())) {
                        contains = true;
                        break;
                    }
                }
                // If the super has a mapping that wasn't processed by the subclasses, add it to be processed
                if(!contains) {
                    hiddenMappings.add(mapping);
                }
            }
            unMappedAttributes.addAll(hiddenMappings);
        }

        boolean weaveValueHolders = canWeaveValueHolders(superClz, unMappedAttributes);

        List<DatabaseMapping> stillUnMappedMappings = null;
        ClassDetails superClassDetails = createClassDetails(superClz, weaveValueHolders, weaveChangeTracking, weaveFetchGroups, weaveInternal, weaveRest);
        superClassDetails.setIsMappedSuperClass(true);

        if (mappedSuperclassDescriptor != null && ! mappedSuperclassDescriptor.usesPropertyAccessForWeaving()) {
            superClassDetails.useAttributeAccess();
        } else if (!initialDescriptor.usesPropertyAccessForWeaving()){
            superClassDetails.useAttributeAccess();
        }

        if (!classDetailsMap.containsKey(superClassDetails.getClassName())){
            stillUnMappedMappings = storeAttributeMappings(superClz, superClassDetails, unMappedAttributes, weaveValueHolders);
            classDetailsMap.put(superClassDetails.getClassName() ,superClassDetails);
            addClassDetailsForMappedSuperClasses(superClz, initialDescriptor, classDetails, classDetailsMap, stillUnMappedMappings, weaveChangeTracking);
        }
    }

    public PersistenceWeaver buildPersistenceWeaver() {
        return new PersistenceWeaver(classDetailsMap);
    }

    /**
     * Build a list ClassDetails instance that contains a ClassDetails for each class
     * in our entities list.
     */
    public void buildClassDetailsAndModifyProject() {
        if (entityClasses != null && entityClasses.size() > 0) {
            // scan thru list building details of persistent classes
            for (MetadataClass metaClass : entityClasses) {
                // check to ensure that class is present in project
                // this will be a relational descriptor because MetadataClass only describes relational descriptors
                boolean isMappedSuperclass = false;
                ClassDescriptor descriptor = findDescriptor(session.getProject(), metaClass.getName());
                if (descriptor == null) {
                    if (weaveMappedSuperClass) {
                        //Bug #466271 - find mapped superclasses which have no implementation
                        descriptor = session.getProject().getMappedSuperclass(metaClass.getName());
                        if (descriptor == null) {
                            log(SessionLog.FINER, WEAVER_CLASS_NOT_IN_PROJECT, new Object[]{metaClass.getName()});
                            continue;
                        } else {
                            isMappedSuperclass = true;
                        }
                    } else {
                        log(SessionLog.FINER, WEAVER_CLASS_NOT_IN_PROJECT, new Object[]{metaClass.getName()});
                        continue;
                    }
                }
                log(SessionLog.FINER, WEAVER_PROCESSING_CLASS, new Object[]{metaClass.getName()});

                boolean weaveValueHoldersForClass = weaveLazy && canWeaveValueHolders(metaClass, descriptor.getMappings());
                boolean weaveChangeTrackingForClass = canChangeTrackingBeEnabled(descriptor, metaClass, weaveChangeTracking);

                ClassDetails classDetails = createClassDetails(metaClass, weaveValueHoldersForClass, weaveChangeTrackingForClass, weaveFetchGroups, weaveInternal, weaveRest);
                classDetails.setIsMappedSuperClass(isMappedSuperclass);
                if (descriptor.isDescriptorTypeAggregate()) {
                    classDetails.setIsEmbedable(true);
//                    classDetails.setShouldWeaveFetchGroups(false);
                }

                if (!descriptor.usesPropertyAccessForWeaving()){
                    classDetails.useAttributeAccess();
                }

                classDetails.getVirtualAccessMethods().addAll(descriptor.getVirtualAttributeMethods());

                List<DatabaseMapping> unMappedAttributes = storeAttributeMappings(metaClass, classDetails, descriptor.getMappings(), weaveValueHoldersForClass);
                classDetailsMap.put(classDetails.getClassName() ,classDetails);

                classDetails.setShouldWeaveConstructorOptimization((classDetails.getDescribedClass().getFields().size() - (descriptor.getMappings().size() - unMappedAttributes.size()))<=0);

                if (classDetails.getSuperClassName() != null) {
                    addClassDetailsForMappedSuperClasses(metaClass, descriptor, classDetails, classDetailsMap, unMappedAttributes, weaveChangeTracking);
                }
            }

            // hookup superClassDetails
            for (Iterator<ClassDetails> i = classDetailsMap.values().iterator(); i.hasNext();) {
                ClassDetails classDetails = i.next();
                ClassDetails superClassDetails = classDetailsMap.get(classDetails.getSuperClassName());
                if (superClassDetails == null) {
                    ClassDescriptor descriptor = findDescriptor(session.getProject(), classDetails.getDescribedClass().getName());
                    if (descriptor != null && descriptor.hasInheritance()){
                        superClassDetails = classDetailsMap.get(descriptor.getInheritancePolicy().getParentClassName());
                    }
                }
                if (superClassDetails != null) {
                    classDetails.setSuperClassDetails(superClassDetails);
                }
            }

            // Fix weaveChangeTracking based on superclasses,
            // we should only weave change tracking if our whole hierarchy can.
            for (Iterator<ClassDetails> i = classDetailsMap.values().iterator(); i.hasNext();) {
                ClassDetails classDetails = i.next();
                classDetails.setShouldWeaveChangeTracking(classDetails.canWeaveChangeTracking());
            }
        }
    }

    /**
     * Check to ensure the class meets all the conditions necessary to enable change tracking
     * This could occur either if the class already has change tracking implemented or if the
     * class is capable of having change tracking woven based on the descriptor.
     */
    protected boolean canChangeTrackingBeEnabled(ClassDescriptor descriptor, MetadataClass clz, boolean globalWeaveChangeTracking) {
        if (!globalWeaveChangeTracking) {
          return false;
        }
        // If the descriptor was configured to not use change tracking then disable it, also enable if configure explictly.
        if (descriptor.getObjectChangePolicyInternal() != null) {
            if (descriptor.getObjectChangePolicyInternal().isDeferredChangeDetectionPolicy()) {
                return false;
            } else if (descriptor.getObjectChangePolicyInternal().isObjectChangeTrackingPolicy()) {
                // Include object and attribute.
                return true;
            }
        }
        boolean canWeaveChangeTracking = descriptor.supportsChangeTracking(session.getProject());
        if (!canWeaveChangeTracking) {
            log(SessionLog.CONFIG, CANNOT_WEAVE_CHANGETRACKING, new Object[]{descriptor.getJavaClassName()});
        }
        return canWeaveChangeTracking;
    }

    protected boolean wasChangeTrackingAlreadyWeaved(Class<?> clz){
        Class<?>[] interfaces = clz.getInterfaces();
        for (int i = 0; i < interfaces.length; i++) {
            Class<?> c = interfaces[i];
            if (c.getName().equals(PersistenceWeavedChangeTracking.class.getName())){
                return true;
            }
        }
        return false;
    }

    /**
     * Determine if value holders are required to be weaved into the class.
     */
    protected boolean canWeaveValueHolders(MetadataClass clz, List<DatabaseMapping> mappings) {
        // we intend to change to fetch=LAZY 1:1 attributes to ValueHolders
        boolean weaveValueHolders = false;
        for (Iterator<DatabaseMapping> iterator = mappings.iterator(); iterator.hasNext();) {
            DatabaseMapping mapping = iterator.next();
            String attributeName = mapping.getAttributeName();
            if (mapping.isForeignReferenceMapping()) {
                ForeignReferenceMapping foreignReferenceMapping = (ForeignReferenceMapping)mapping;
                MetadataClass typeClass = getAttributeTypeFromClass(clz, attributeName, foreignReferenceMapping, true);
                if ((foreignReferenceMapping.getIndirectionPolicy() instanceof BasicIndirectionPolicy) &&
                        (typeClass != null)  && (!typeClass.extendsInterface(ValueHolderInterface.class))) {
                    weaveValueHolders = true;
                 }
             }
        }
        return weaveValueHolders;
    }

    private ClassDetails createClassDetails(MetadataClass metadataClass, boolean weaveValueHolders, boolean weaveChangeTracking, boolean weaveFetchGroups, boolean weaveInternal, boolean weaveRest) {
        // compose className in JVM 'slash' format
        // instead of regular Java 'dotted' format
        String className = Helper.toSlashedClassName(metadataClass.getName());
        String superClassName = Helper.toSlashedClassName(metadataClass.getSuperclass().getName());
        ClassDetails classDetails = new ClassDetails();
        classDetails.setDescribedClass(metadataClass);
        classDetails.setClassName(className);
        classDetails.setSuperClassName(superClassName);
        classDetails.setShouldWeaveValueHolders(weaveValueHolders);
        classDetails.setShouldWeaveChangeTracking(weaveChangeTracking);
        classDetails.setShouldWeaveFetchGroups(weaveFetchGroups);
        classDetails.setShouldWeaveInternal(weaveInternal);
        classDetails.setShouldWeaveREST(weaveRest);
        MetadataMethod method = metadataClass.getMethod("clone", new ArrayList<>(), false);
        classDetails.setImplementsCloneMethod(method != null);
        return classDetails;
    }

    /**
     * Find a descriptor by name in the given project
     * used to avoid referring to descriptors by class.
     * This avoids having to construct a project by class facilitating weaving
     */
    protected ClassDescriptor findDescriptor(Project project, String className){
        Iterator<ClassDescriptor> iterator = project.getOrderedDescriptors().iterator();
        while (iterator.hasNext()){
            ClassDescriptor descriptor = iterator.next();
            if (descriptor.getJavaClassName().equals(className)){
                return descriptor;
            }
        }
        return null;
    }

    /**
     * Return if the class contains the field.
     */
    protected boolean hasFieldInClass(MetadataClass metadataClass, String attributeName) {
        return metadataClass.getField(attributeName) != null;
    }

    /**
     * Return the class which is the source of the attribute.
     * i.e. the class that defines the attribute in its class file.
     */
    private MetadataClass getAttributeDeclaringClass(MetadataClass metadataClass, String attributeName) {
        MetadataField field = metadataClass.getField(attributeName);
        return field.getDeclaringClass();
    }

    /**
     * Use the database mapping for an attribute to find it's type.  The type returned will either be
     * the field type of the field in the object or the type returned by the getter method.
     */
    private MetadataClass getAttributeTypeFromClass(MetadataClass metadataClass, String attributeName, DatabaseMapping mapping, boolean checkSuperclass){
        String getterMethod = mapping.getGetMethodName();
        if (mapping.isAbstractDirectMapping() && mapping.getAttributeAccessor().isVirtualAttributeAccessor()){
            return metadataClass.getMetadataClass(((AbstractDirectMapping)mapping).getAttributeClassificationName());
        } else if (getterMethod != null) {
            MetadataMethod method = metadataClass.getMethod(getterMethod, new ArrayList<>(), checkSuperclass);
            if (method == null) {
                return null;
            }
            return method.getMetadataClass(method.getReturnType());
        } else {
            MetadataField field = metadataClass.getField(attributeName, checkSuperclass);
            if (field == null) {
                return null;
            }
            return field.getMetadataClass(field.getType());
        }
    }

    /**
     *  INTERNAL:
     *  Store a set of attribute mappings on the given ClassDetails that correspond to the given class.
     *  Return the list of mappings that is not specifically found on the given class.  These attributes will
     *  be found on MappedSuperclasses.
     */
    protected List<DatabaseMapping> storeAttributeMappings(MetadataClass metadataClass, ClassDetails classDetails, List<DatabaseMapping> mappings, boolean weaveValueHolders) {
        List<DatabaseMapping> unMappedAttributes = new ArrayList<>();
        Map<String, AttributeDetails> attributesMap = new HashMap<String, AttributeDetails>();
        Map<String, AttributeDetails> settersMap = new HashMap<String, AttributeDetails>();
        Map<String, AttributeDetails> gettersMap = new HashMap<String, AttributeDetails>();

        for (Iterator<DatabaseMapping> iterator = mappings.iterator(); iterator.hasNext();) {
            DatabaseMapping mapping = iterator.next();

            // Can't weave something that isn't really there and not going to be there.
            if (mapping.isMultitenantPrimaryKeyMapping()) {
                continue;
            }

            String attribute = mapping.getAttributeName();
            AttributeDetails attributeDetails = new AttributeDetails(attribute, mapping);

            if (mapping.getAttributeAccessor().isVirtualAttributeAccessor()){
                attributeDetails.setVirtualProperty(mapping.getAttributeAccessor().isVirtualAttributeAccessor());
                if ((classDetails.getInfoForVirtualGetMethod(mapping.getGetMethodName()) == null) && (classDetails.getInfoForVirtualSetMethod(mapping.getSetMethodName()) == null)){
                    VirtualAttributeMethodInfo info = new VirtualAttributeMethodInfo(mapping.getGetMethodName(), mapping.getSetMethodName());
                    classDetails.getVirtualAccessMethods().add(info);
                }
            }
            // Initial look for the type of this attribute.
            MetadataClass typeClass = getAttributeTypeFromClass(metadataClass, attribute, mapping, false);
            if (typeClass == null) {
                attributeDetails.setAttributeOnSuperClass(true);
                unMappedAttributes.add(mapping);
            }

            // Set the getter and setter method names if the mapping uses property access.
            if (mapping.getGetMethodName() != null) {
                gettersMap.put(mapping.getGetMethodName(), attributeDetails);
                attributeDetails.setGetterMethodName(mapping.getGetMethodName());
                if (mapping.getSetMethodName() != null) {
                    settersMap.put(mapping.getSetMethodName(), attributeDetails);
                    attributeDetails.setSetterMethodName(mapping.getSetMethodName());
                }

                if (mapping.isForeignReferenceMapping() && ((ForeignReferenceMapping) mapping).requiresTransientWeavedFields()) {
                    attributeDetails.setWeaveTransientFieldValueHolders();
                }

                // If the property has a matching field, then weave it instead (unless internal weaving is disabled).
                if (this.weaveInternal) {
                    attributeDetails.setHasField(hasFieldInClass(metadataClass, attribute));
                }
            } else {
                attributeDetails.setHasField(true);
            }
            // If the attribute has a field, then the weaver needs to know in which class it was defined.
            if (attributeDetails.hasField()) {
                attributeDetails.setDeclaringType(Type.getType(getAttributeDeclaringClass(metadataClass, attribute).getTypeName()));
            }

            // Check for lazy/value-holder indirection.
            if (mapping.isForeignReferenceMapping()) {
                ForeignReferenceMapping foreignReferenceMapping = (ForeignReferenceMapping)mapping;

                // repopulate the reference class with the target of this mapping
                attributeDetails.setReferenceClassName(foreignReferenceMapping.getReferenceClassName());
                if (attributeDetails.getReferenceClassName() != null) {
                    MetadataClass referenceClass = metadataClass.getMetadataFactory().getMetadataClass(attributeDetails.getReferenceClassName());
                    attributeDetails.setReferenceClassType(Type.getType(referenceClass.getTypeName()));
                }

                // This time, look up the type class and include the superclass so we can check for lazy.
                if (typeClass == null){
                    typeClass = getAttributeTypeFromClass(metadataClass, attribute, foreignReferenceMapping, true);
                }
                if (weaveValueHolders && (foreignReferenceMapping.getIndirectionPolicy() instanceof BasicIndirectionPolicy) &&
                        (typeClass != null)  && (!typeClass.extendsInterface(ValueHolderInterface.class))) {
                    if (mapping.isObjectReferenceMapping() && attributeDetails.isVirtualProperty()){
                        classDetails.setShouldWeaveValueHolders(false);
                        log(SessionLog.WARNING, CANNOT_WEAVE_VIRTUAL_ONE_TO_ONE, new Object[]{classDetails.getClassName(), attributeDetails.getAttributeName()});
                    } else {
                        attributeDetails.weaveVH(weaveValueHolders, foreignReferenceMapping);
                    }
                }
            }

            if (attributeDetails.getReferenceClassType() == null){
                if (typeClass == null){
                    typeClass = getAttributeTypeFromClass(metadataClass, attribute, mapping, true);
                }
            }
            if (typeClass != null) {
                attributeDetails.setReferenceClassName(typeClass.getName());
                attributeDetails.setReferenceClassType(Type.getType(typeClass.getTypeName()));
            }
            attributesMap.put(attribute, attributeDetails);
        }
        classDetails.setAttributesMap(attributesMap);
        classDetails.setGetterMethodToAttributeDetails(gettersMap);
        classDetails.setSetterMethodToAttributeDetails(settersMap);
        return unMappedAttributes;
    }

    protected void log(int level, String msg, Object[] params) {
        ((org.eclipse.persistence.internal.sessions.AbstractSession)session).log(level,
            SessionLog.WEAVER, msg, params);
    }

}
