/*
 * 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
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
     */
    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
     */
    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
     */
    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
     *
     */
    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
     *
     */
    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;
    }

}
