/*
 * Copyright (c) 1998, 2020 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.internal.jpa.weaving;

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

import org.eclipse.persistence.internal.descriptors.VirtualAttributeMethodInfo;
import org.eclipse.persistence.internal.jpa.metadata.accessors.objects.MetadataClass;

/**
 * Internal helper class that holds details of a persistent class.
 * Used by {@link PersistenceWeaver}
 */

public class ClassDetails {

    protected MetadataClass describedClass;
    /** Name of this class. */
    protected String className;
    /** Superclass' name. */
    protected String superClassName;
    /** Superclass' ClassDetails - only populated if superclass is also persistent. */
    protected ClassDetails superClassDetails;
    /** Define if lazy value holders should be weaved in this class. */
    protected boolean shouldWeaveValueHolders = false;
    /** Define if change tracking should be weaved in this class. */
    protected boolean shouldWeaveChangeTracking = false;
    /** Define if fetch groups should be weaved in this class. */
    protected boolean shouldWeaveFetchGroups = false;
    /** Define if internal optimizations should be weaved in this class. */
    protected boolean shouldWeaveInternal = false;
    /** Define if this class should be weaved for our REST support */
    protected boolean shouldWeaveRest = false;
    /** Map of this class' persistent attributes where the key is the Attribute name. */
    protected Map<String, AttributeDetails> attributesMap;
    /** Map of this class' persistent get methods where the key is the getMethod name. */
    protected Map<String, AttributeDetails> getterMethodToAttributeDetails;
    /** Map of this class' persistent set methods where the key is the setMethod name. */
    protected Map<String, AttributeDetails> setterMethodToAttributeDetails;
    /** Determine if a JPA "mapped superclass". */
    protected boolean isMappedSuperClass = false;
    /** Determine if a JPA "embedable" (aggregate). */
    protected boolean isEmbedable = false;
    /** Determine if class uses attribute access, lazily initialized. */
    protected boolean usesAttributeAccess = false;
    /** Determine if this class specifically implements a clone method */
    protected boolean implementsCloneMethod = false;
    /** Determine if a new constructor can be used to bypass setting variables to default values. */
    protected boolean shouldWeaveConstructorOptimization = true;
    /** The methods that are used by virtual attributes as getter methods.
     * These will be used by our weaver to properly weave those methods
     * This list should be kept in sync with virtualSetMethodNames. Every time
     * a value is added, one should be added to virtualSetMethodNames so that at
     * a particular index, the virtualGetMethodName and the virtualSetMethodCoorespond*/
    protected List<VirtualAttributeMethodInfo> virtualAccessMethods = null;


    public ClassDetails() {
        virtualAccessMethods = new ArrayList<VirtualAttributeMethodInfo>();
    }

    public MetadataClass getDescribedClass(){
        return describedClass;
    }

    public String getClassName() {
        return className;
    }

    public void setDescribedClass(MetadataClass describedClass){
        this.describedClass = describedClass;
    }

    public void setClassName(String className) {
        this.className = className;
    }

    public String getSuperClassName() {
        return superClassName;
    }

    public void setSuperClassName(String superClassName) {
        this.superClassName = superClassName;
    }

    public ClassDetails getSuperClassDetails() {
        return superClassDetails;
    }

    public void setSuperClassDetails(ClassDetails superClassDetails) {
        this.superClassDetails = superClassDetails;
    }

    public boolean shouldWeaveValueHolders() {
        return shouldWeaveValueHolders;
    }

    public void setShouldWeaveValueHolders(boolean shouldWeaveValueHolders) {
        this.shouldWeaveValueHolders = shouldWeaveValueHolders;
    }

    public boolean shouldWeaveChangeTracking() {
        return shouldWeaveChangeTracking;
    }

    public void setShouldWeaveChangeTracking(boolean shouldWeaveChangeTracking) {
        this.shouldWeaveChangeTracking = shouldWeaveChangeTracking;
    }

    public void setShouldWeaveConstructorOptimization(boolean shouldWeaveConstructorOptimization) {
        this.shouldWeaveConstructorOptimization = shouldWeaveConstructorOptimization;
    }

    public boolean shouldWeaveFetchGroups() {
        return shouldWeaveFetchGroups;
    }

    public void setShouldWeaveFetchGroups(boolean shouldWeaveFetchGroups) {
        this.shouldWeaveFetchGroups = shouldWeaveFetchGroups;
    }

    public boolean shouldWeaveInternal() {
        return shouldWeaveInternal;
    }

    public void setShouldWeaveInternal(boolean shouldWeaveInternal) {
        this.shouldWeaveInternal = shouldWeaveInternal;
    }

    public boolean shouldWeaveREST(){
        return shouldWeaveRest;
    }

    public void setShouldWeaveREST(boolean shouldWeaveRest){
        this.shouldWeaveRest = shouldWeaveRest;
    }

    public Map<String, AttributeDetails> getAttributesMap() {
        return attributesMap;
    }

    public Map<String, AttributeDetails> getGetterMethodToAttributeDetails(){
        return getterMethodToAttributeDetails;
    }

    public Map<String, AttributeDetails> getSetterMethodToAttributeDetails(){
        return setterMethodToAttributeDetails;
    }

    public void setAttributesMap(Map<String, AttributeDetails> attributesMap) {
        this.attributesMap = attributesMap;
    }

    public void setGetterMethodToAttributeDetails(Map<String, AttributeDetails> map){
        this.getterMethodToAttributeDetails = map;
    }

    public boolean getImplementsCloneMethod(){
        return implementsCloneMethod;
    }

    /**
     * INTERNAL:
     * Search the list of virtualAccessMethods for a VirtualAttributeMethodInfo with the given
     * getMethodName.  Return the VirtualAttributeMethodInfo if there is one, else return null
     * @param getMethodName
     * @return
     */
    public VirtualAttributeMethodInfo getInfoForVirtualGetMethod(String getMethodName){
        Iterator<VirtualAttributeMethodInfo> i = virtualAccessMethods.iterator();
        while (i.hasNext()){
            VirtualAttributeMethodInfo info = i.next();
            if (info.getGetMethodName() != null && info.getGetMethodName().equals(getMethodName)){
                return info;
            }
        }
        return null;
    }

    /**
     * INTERNAL:
     * Search the list of virtualAccessMethods for a VirtualAttributeMethodInfo with the given
     * setMethodName.  Return the VirtualAttributeMethodInfo if there is one, else return null
     * @param setMethodName
     * @return
     */
    public VirtualAttributeMethodInfo getInfoForVirtualSetMethod(String setMethodName){
        Iterator<VirtualAttributeMethodInfo> i = virtualAccessMethods.iterator();
        while (i.hasNext()){
            VirtualAttributeMethodInfo info = i.next();
            if (info.getGetMethodName() != null && info.getGetMethodName().equals(setMethodName)){
                return info;
            }
        }
        return null;
    }

    public void setImplementsCloneMethod(boolean implementsCloneMethod){
        this.implementsCloneMethod = implementsCloneMethod;
    }

    /**
     * Return the name of the most direct superclass that has a direct implementation of
     * a clone method.
     * If there is not one, return null
     * @return
     */
    public String getNameOfSuperclassImplementingCloneMethod(){
        if (superClassDetails == null){
            return null;
        } else if (superClassDetails.getImplementsCloneMethod()){
            return superClassDetails.getClassName();
        } else {
            return superClassDetails.getNameOfSuperclassImplementingCloneMethod();
        }
    }

    public List<VirtualAttributeMethodInfo> getVirtualAccessMethods() {
        return virtualAccessMethods;
    }

    public void setVirtualAccessMethods(List<VirtualAttributeMethodInfo> virtualAccessMethods) {
        this.virtualAccessMethods = virtualAccessMethods;
    }

    public boolean isMappedSuperClass(){
        return isMappedSuperClass;
    }

    public void setIsMappedSuperClass(boolean isMappedSuperClass){
        this.isMappedSuperClass = isMappedSuperClass;
    }

    public boolean isEmbedable(){
        return isEmbedable;
    }

    public void setIsEmbedable(boolean isEmbedable){
        this.isEmbedable = isEmbedable;
    }

    public void setSetterMethodToAttributeDetails(Map map){
        this.setterMethodToAttributeDetails = map;
    }

    /**
     * If one attribute of this class uses attribute access, by the JPA specification, all
     * attributes must use attribute access
     *
     * This method assumes it is called when this class details is completely initialized.
     */
    public boolean usesAttributeAccess() {
        return usesAttributeAccess;
    }

    public void useAttributeAccess(){
        usesAttributeAccess = true;
    }

    public AttributeDetails getAttributeDetailsFromClassOrSuperClass(String attributeName){
        AttributeDetails attribute = attributesMap.get(attributeName);
        if (attribute == null && superClassDetails != null) {
            return superClassDetails.getAttributeDetailsFromClassOrSuperClass(attributeName);
        }
       return attribute;
    }

    public boolean doesSuperclassWeaveChangeTracking(){
        if (getSuperClassDetails() == null){
            return false;
        }
        if (getSuperClassDetails().shouldWeaveChangeTracking()) {
            return true;
        }

        return getSuperClassDetails().doesSuperclassWeaveChangeTracking();
    }

    public boolean canWeaveChangeTracking(){
        if ((getSuperClassDetails() == null) || (!shouldWeaveChangeTracking())) {
            return shouldWeaveChangeTracking();
        }

        return getSuperClassDetails().canWeaveChangeTracking();
    }

    /**
     * Returns true if
     * Used with field access, and is set to false if transient variables are discovered
     */
    public boolean canWeaveConstructorOptimization(){
        if (!shouldWeaveConstructorOptimization || (getSuperClassDetails() == null)) {
            return shouldWeaveConstructorOptimization;
        }
        return getSuperClassDetails().canWeaveConstructorOptimization();
    }

    /**
     * Returns true if the given class name represents this class, or any
     * superclass that can be navigated to by recursively navigating up the
     * structure of superClassDetails stored in this class.
     *
     * Assume java.lang.Object is in the hierarchy
     *
     * @param className
     * @return
     */
    public boolean isInMetadataHierarchy(String className){
        if (className.equals(Object.class.getName().replace('.', '/'))){
            return true;
        }
        if (className.equals(this.className) || (superClassName != null && className.equals(superClassName))){
            return true;
        }
        if (superClassDetails != null){
            return superClassDetails.isInMetadataHierarchy(className);
        }
        return false;
    }

    /**
     * Returns true if the given class name represents this class, or any
     * superclass that can be navigated to by recursively navigating up the
     * structure of superClassDetails stored in this class.
     *
     * Assume java.lang.Object is in the hierarchy
     *
     * @param className
     * @return
     */
    public boolean isInSuperclassHierarchy(String className){
        if (className.equals(Object.class.getName().replace('.', '/'))){
            return true;
        }
        if (superClassName != null && className.equals(superClassName)){
            return true;
        }
        if (superClassDetails != null){
            return superClassDetails.isInMetadataHierarchy(className);
        }
        return false;
    }

}
