/*
 * Copyright (c) 2011, 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:
//     03/19/2009-2.0  dclarke  - initial API start
//     06/30/2009-2.0  mobrien - finish JPA Metadata API modifications in support
//       of the Metamodel implementation for EclipseLink 2.0 release involving
//       Map, ElementCollection and Embeddable types on MappedSuperclass descriptors
//       - 266912: JPA 2.0 Metamodel API (part of the JSR-317 EJB 3.1 Criteria API)
//     29/10/2009-2.0  mobrien - m:1 and 1:m relationships require special handling
//       in their internal m:m and 1:1 database mapping representations.
//       http://wiki.eclipse.org/EclipseLink/Development/JPA_2.0/metamodel_api#DI_96:_20091019:_Attribute.getPersistentAttributeType.28.29_treats_ManyToOne_the_same_as_OneToOne
//     16/06/2010-2.2  mobrien - 316991: Attribute.getJavaMember() requires reflective getMethod call
//       when only getMethodName is available on accessor for attributes of Embeddable types.
//       http://wiki.eclipse.org/EclipseLink/Development/JPA_2.0/metamodel_api#DI_95:_20091017:_Attribute.getJavaMember.28.29_returns_null_for_a_BasicType_on_a_MappedSuperclass_because_of_an_uninitialized_accessor
//     09/08/2010-2.2  mobrien - 322166: If attribute is defined on a lower level MappedSuperclass (and not on a superclass)
//       - do not attempt a reflective call on a superclass
//       - see design issue #25
//       http://wiki.eclipse.org/EclipseLink/Development/JPA_2.0/metamodel_api#DI_25:_20090616:_Inherited_parameterized_generics_for_Element_Collections_.28Basic.29
//     11/10/2011-2.4 Guy Pelletier
//       - 357474: Address primaryKey option from tenant discriminator column
package org.eclipse.persistence.internal.jpa.metamodel;

import java.io.Serializable;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedActionException;

import jakarta.persistence.metamodel.Attribute;
import jakarta.persistence.metamodel.ManagedType;

import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.internal.descriptors.InstanceVariableAttributeAccessor;
import org.eclipse.persistence.internal.descriptors.MethodAttributeAccessor;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.internal.security.PrivilegedGetDeclaredField;
import org.eclipse.persistence.internal.security.PrivilegedGetDeclaredMethod;
import org.eclipse.persistence.logging.AbstractSessionLog;
import org.eclipse.persistence.logging.SessionLog;
import org.eclipse.persistence.mappings.AttributeAccessor;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.mappings.ManyToManyMapping;

/**
 * <p>
 * <b>Purpose</b>: Provides the implementation for the Attribute interface
 *  of the JPA 2.0 Metamodel API (part of the JSR-317 EJB 3.1 Criteria API)
 * <p>
 * <b>Description</b>:
 * An attribute of a Java type
 *
 * @see jakarta.persistence.metamodel.Attribute
 *
 * @since EclipseLink 1.2 - JPA 2.0
 * @param <X> The represented type that contains the attribute
 * @param <T> The type of the represented attribute
 *
 */
public abstract class AttributeImpl<X, T> implements Attribute<X, T>, Serializable {

    /** The ManagedType associated with this attribute **/
    private ManagedTypeImpl<X> managedType;

    /** The databaseMapping associated with this attribute **/
    private DatabaseMapping mapping;

    /**
     * INTERNAL:
     *
     */
    protected AttributeImpl(ManagedTypeImpl<X> managedType, DatabaseMapping mapping) {
        this.mapping = mapping;
        // Cache this Attribute on the mapping - Why??
        //this.mapping.setProperty(getClass().getName(), this);
        this.managedType = managedType;
    }

    /**
     *  Return the managed type representing the type in which
     *  the attribute was declared.
     *  @return declaring type
     */
    @Override
    public ManagedType<X> getDeclaringType() {
        return getManagedTypeImpl();
    }

    /**
     * INTERNAL:
     * Return the Descriptor associated with this attribute
     */
    protected ClassDescriptor getDescriptor() {
        return getManagedTypeImpl().getDescriptor();
    }

    /**
     * Return the java.lang.reflect.Member for the represented attribute.
     * In the case of property access the get method will be returned
     *
     * @return corresponding java.lang.reflect.Member
     */
    @Override
    public Member getJavaMember() {
        AttributeAccessor accessor = getMapping().getAttributeAccessor();
        if (accessor.isMethodAttributeAccessor()) {
            // Method level access here
            Method aMethod = ((MethodAttributeAccessor) accessor).getGetMethod();
            if(null == aMethod) {
                // 316991: If the getMethod is not set - use a reflective call via the getMethodName
                String getMethodName = null;
                try {
                    getMethodName = ((MethodAttributeAccessor)mapping.getAttributeAccessor()).getGetMethodName();
                    if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()) {
                        aMethod = AccessController.doPrivileged(new PrivilegedGetDeclaredMethod(
                                this.getManagedTypeImpl().getJavaType(), getMethodName, null));
                    } else {
                        aMethod = PrivilegedAccessHelper.getDeclaredMethod(
                                this.getManagedTypeImpl().getJavaType(),getMethodName, null);
                    }
                    // Exceptions are to be ignored for reflective calls - if the methodName is also null - it will catch here
                } catch (PrivilegedActionException pae) {
                    //pae.printStackTrace();
                } catch (NoSuchMethodException nsfe) {
                    //nsfe.printStackTrace();
                }
            }
            return aMethod;
        }

        // Field level access here
        Member aMember = ((InstanceVariableAttributeAccessor) accessor).getAttributeField();
        // For primitive and basic types - we should not return null - the attributeAccessor on the MappedSuperclass is not initialized - see
        // http://wiki.eclipse.org/EclipseLink/Development/JPA_2.0/metamodel_api#DI_95:_20091017:_Attribute.getJavaMember.28.29_returns_null_for_a_BasicType_on_a_MappedSuperclass_because_of_an_uninitialized_accessor
        // MappedSuperclasses need special handling to get their type from an inheriting subclass
        // Note: This code does not handle attribute overrides on any entity subclass tree - use descriptor initialization instead
        if(null == aMember) {
            if(this.getManagedTypeImpl().isMappedSuperclass()) {
                // get inheriting subtype member (without handling @override annotations)
                AttributeImpl inheritingTypeMember = ((MappedSuperclassTypeImpl)this.getManagedTypeImpl())
                    .getMemberFromInheritingType(mapping.getAttributeName());
                // 322166: If attribute is defined on this current ManagedType (and not on a superclass) - do not attempt a reflective call on a superclass
                if(null != inheritingTypeMember) {
                    // Verify we have an attributeAccessor
                    aMember = ((InstanceVariableAttributeAccessor)inheritingTypeMember.getMapping()
                            .getAttributeAccessor()).getAttributeField();
                }
            }

            if(null == aMember) {
                // 316991: Handle Embeddable types
                // If field level access - perform a getDeclaredField call
                // Field level access
                // Check declaredFields in the case where we have no getMethod or getMethodName
                try {
                    if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                        aMember = AccessController.doPrivileged(new PrivilegedGetDeclaredField(
                            this.getManagedTypeImpl().getJavaType(), mapping.getAttributeName(), false));
                    } else {
                        aMember = PrivilegedAccessHelper.getDeclaredField(
                            this.getManagedTypeImpl().getJavaType(), mapping.getAttributeName(), false);
                    }
                    // Exceptions are to be ignored for reflective calls - if the methodName is also null - it will catch here
                } catch (PrivilegedActionException pae) {
                    //pae.printStackTrace();
                } catch (NoSuchFieldException nsfe) {
                    //nsfe.printStackTrace();
                }
            }
        }

        // 303063: secondary check for attribute override case - this will show on code coverage
        if(null == aMember) {
            AbstractSessionLog.getLog().log(SessionLog.FINEST, AbstractSessionLog.METAMODEL, "metamodel_attribute_getmember_is_null", this, this.getManagedTypeImpl(), this.getDescriptor());
        }

        return aMember;
    }

    /**
     *  Return the Java type of the represented attribute.
     *  @return Java type
     */
    @Override
    public abstract Class<T> getJavaType();

    /**
     * INTERNAL:
     * Return the managed type representing the type in which the member was
     * declared.
     */
    public ManagedTypeImpl<X> getManagedTypeImpl() {
        return this.managedType;
    }

    /**
     * INTERNAL:
     * Return the databaseMapping that represents the type
     */
    public DatabaseMapping getMapping() {
        return this.mapping;
    }

    /**
     * INTERNAL:
     * Return the concrete metamodel that this attribute is associated with.
     * @return MetamodelImpl
     */
    protected MetamodelImpl getMetamodel() {
        return this.managedType.getMetamodel();
    }

    /**
     * Return the name of the attribute.
     * @return name
     */
    @Override
    public String getName() {
        return this.getMapping().getAttributeName();
    }

    /**
     *  Return the persistent attribute type for the attribute.
     *  @return persistent attribute type
     */
    @Override
    public Attribute.PersistentAttributeType getPersistentAttributeType() {
        /**
         * process the following mappings by referencing the Core API Mapping.
         * MANY_TO_ONE (ONE_TO_ONE internally)
         * ONE_TO_ONE (May originally be a MANY_TO_ONE)
         * BASIC
         * EMBEDDED
         * MANY_TO_MANY (May originally be a unidirectional ONE_TO_MANY on a mappedSuperclass)
         * ONE_TO_MANY (MANY_TO_MANY internally for unidirectional mappings on MappedSuperclasses)
         * ELEMENT_COLLECTION
         */
        if (mapping.isAbstractDirectMapping()) {
            return PersistentAttributeType.BASIC;
        }
        if (mapping.isAggregateObjectMapping()) {
            return PersistentAttributeType.EMBEDDED;
        }
        if (mapping.isOneToManyMapping()) {
            return PersistentAttributeType.ONE_TO_MANY;
        }

        /**
         * EclipseLink internally processes a ONE_TO_MANY on a MappedSuperclass as a MANY_TO_MANY
         * because the relationship is unidirectional.
         */
        if (mapping.isManyToManyMapping()) {
            // Check for a OneToMany on a MappedSuperclass being processed internally as a ManyToMany
            if(((ManyToManyMapping)mapping).isDefinedAsOneToManyMapping()) {
                return PersistentAttributeType.ONE_TO_MANY;
            } else {
                // Test coverage required
                return PersistentAttributeType.MANY_TO_MANY;
            }
        }

        if (mapping.isManyToOneMapping()) {
            return PersistentAttributeType.MANY_TO_ONE;
        }
        if (mapping.isOneToOneMapping()) {
            return PersistentAttributeType.ONE_TO_ONE;
        }
        // Test coverage required
        return PersistentAttributeType.ELEMENT_COLLECTION;
    }

    /**
     *  Is the attribute an association.
     *  @return whether boolean indicating whether attribute
     *          corresponds to an association
     */
    @Override
    public boolean isAssociation() {
        // If the mapping a relationship to another entity.
        return getMapping().isForeignReferenceMapping() && !getMapping().isDirectCollectionMapping()
            && !getMapping().isAggregateCollectionMapping();
    }

    /**
     *  Is the attribute collection-valued.
     *  @return boolean indicating whether attribute is
     *          collection-valued.<p>
     *  This will be true for the mappings CollectionMapping, AbstractCompositeCollectionMapping,
     *  AbstractCompositeDirectCollectionMapping and their subclasses
     *
     */
    @Override
    public boolean isCollection() {
        return getMapping().isCollectionMapping();
    }

    /**
     * INTERNAL:
     * Return whether the attribute is plural or singular
     */
    public abstract boolean isPlural();
}
