/*
 * 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:
//     05/26/2009-2.0  mobrien - API update
//       - 266912: JPA 2.0 Metamodel API (part of the JSR-317 EJB 3.1 Criteria API)
//     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
//     08/06/2010-2.2 mobrien 322018 - reduce protected instance variables to private to enforce encapsulation
//     11/10/2011-2.4 Guy Pelletier
//       - 357474: Address primaryKey option from tenant discriminator column
package org.eclipse.persistence.internal.jpa.metamodel;

import java.lang.reflect.Field;

import jakarta.persistence.metamodel.Bindable;
import jakarta.persistence.metamodel.SingularAttribute;
import jakarta.persistence.metamodel.Type;

import org.eclipse.persistence.internal.descriptors.OptimisticLockingPolicy;
import org.eclipse.persistence.logging.AbstractSessionLog;
import org.eclipse.persistence.logging.SessionLog;
import org.eclipse.persistence.mappings.AggregateMapping;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.mappings.ForeignReferenceMapping;
import org.eclipse.persistence.mappings.VariableOneToOneMapping;
import org.eclipse.persistence.mappings.structures.ReferenceMapping;

/**
 * <p>
 * <b>Purpose</b>: Provides the implementation for the SingularAttribute interface
 *  of the JPA 2.0 Metamodel API (part of the JSR-317 EJB 3.1 Criteria API)
 * <p>
 * <b>Description</b>:
 * Instances of the type SingularAttribute represents persistent
 * single-valued properties or fields.
 *
 * @author Michael O'Brien
 * @see jakarta.persistence.metamodel.SingularAttribute
 * @since EclipseLink 1.2 - JPA 2.0
 *
 * @param <X> The type containing the represented attribute
 * @param <T> The type of the represented attribute
 *
 */
public class SingularAttributeImpl<X, T> extends AttributeImpl<X, T> implements SingularAttribute<X, T> {

    /** Item 54: DI 89: explicit UID will avoid performance hit runtime generation of one */
    private static final long serialVersionUID = 3928292425281232234L;

    /** The Type representing this Entity or Basic type **/
    private Type<T> elementType;

    /**
     * Create an instance of the Attribute
     */
    protected SingularAttributeImpl(ManagedTypeImpl<X> managedType, DatabaseMapping mapping) {
        this(managedType, mapping, false);
    }
    /**
     * INTERNAL:
     * Create an Attribute instance with a passed in validation flag (usually set to true only during Metamodel initialization)
     */
    protected SingularAttributeImpl(ManagedTypeImpl<X> managedType, DatabaseMapping mapping, boolean validationEnabled) {
        super(managedType, mapping);
        // Case: Handle primitive or java lang type (non-Entity) targets
        Class attributeClass = mapping.getAttributeClassification();
        /**
         * Case: Handle Entity targets
         * Process supported mappings by assigning their elementType.
         * For unsupported mappings we default to MetamodelImpl.DEFAULT_ELEMENT_TYPE.
         * If attribute is a primitive type (non-null) - we will wrap it in a BasicType automatically in getType below
         * The attribute classification is null for non-collection mappings such as embeddable keys.
         */
        if (null == attributeClass) {

            // We support @OneToOne but not EIS, Reference or VariableOneToOne
            // Note: OneToMany, ManyToMany are handled by PluralAttributeImpl
            if(mapping instanceof ForeignReferenceMapping) {// handles @ManyToOne
                attributeClass = ((ForeignReferenceMapping)mapping).getReferenceClass();
            } else if (mapping.isAbstractDirectMapping()) { // Also handles the keys of an EmbeddedId
                attributeClass = mapping.getField().getType();
                if(null == attributeClass) {
                    // lookup the attribute on the containing class
                    attributeClass = managedType.getTypeClassFromAttributeOrMethodLevelAccessor(mapping);
                }
            } else if (mapping.isAggregateObjectMapping()) { // IE: EmbeddedId
                attributeClass = ((AggregateMapping)mapping).getReferenceClass();
            } else if (mapping.isVariableOneToOneMapping()) { // interfaces are unsupported in the JPA 2.0 spec for the Metamodel API
                if(validationEnabled) {
                    AbstractSessionLog.getLog().log(SessionLog.FINEST, SessionLog.METAMODEL, "metamodel_mapping_type_is_unsupported", mapping, this);
                }
                // see JUnitCriteriaUnitTestSuite.testSelectPhoneNumberAreaCode() line: 246
                // VariableOneToOne mappings are unsupported - default to referenceClass (Interface) anyway
                // see interface org.eclipse.persistence.testing.models.jpa.relationships.Distributor
                attributeClass = ((VariableOneToOneMapping)mapping).getReferenceClass();
            } else if (mapping.isEISMapping() || mapping.isTransformationMapping()) { // unsupported in the JPA 2.0 spec for the Metamodel API
                if(validationEnabled) {
                    AbstractSessionLog.getLog().log(SessionLog.FINEST, SessionLog.METAMODEL, "metamodel_mapping_type_is_unsupported", mapping, this);
                }
            } else if ( mapping.isReferenceMapping()) { // unsupported in the JPA 2.0 spec for the Metamodel API
                if(validationEnabled) {
                    AbstractSessionLog.getLog().log(SessionLog.FINEST, SessionLog.METAMODEL, "metamodel_mapping_type_is_unsupported", mapping, this);
                }
                // Reference mappings are unsupported - default to referenceClass anyway
                attributeClass = ((ReferenceMapping)mapping).getReferenceClass();
            }
        }
        // All unsupported mappings such as TransformationMapping
        if(null == attributeClass && validationEnabled) {
            // TODO: refactor
            attributeClass = MetamodelImpl.DEFAULT_ELEMENT_TYPE_FOR_UNSUPPORTED_MAPPINGS;
            AbstractSessionLog.getLog().log(SessionLog.FINEST, SessionLog.METAMODEL, "metamodel_attribute_class_type_is_null", this);
        }
        elementType = getMetamodel().getType(attributeClass);
    }

    /**
     * Return the Java type of the represented object.
     * If the bindable type of the object is <code>PLURAL_ATTRIBUTE</code>,
     * the Java element type is returned. If the bindable type is
     * <code>SINGULAR_ATTRIBUTE</code> or <code>ENTITY_TYPE</code>,
     * the Java type of the
     * represented entity or attribute is returned.
     * @return Java type
     */
    @Override
    public Class<T> getBindableJavaType() {
        // In SingularAttribute our BindableType is SINGLE_ATTRIBUTE - return the java type of the represented entity
        return this.elementType.getJavaType();
    }

    /**
     *  Is the attribute an id attribute.
     *  @return boolean indicating whether or not attribute is an id
     */
    @Override
    public boolean isId() {
        if(this.getManagedTypeImpl().isMappedSuperclass()) {
            // The field on the mapping is the same field in the pkFields list on the descriptor
            // 288792: We can use the new isJPAId field here
            return (this.getDescriptor().getPrimaryKeyFields().contains(this.getMapping().getField()));
        } else {
            // 288792: Some id mappings will return false for isPrimaryKeyMapping but true for isJPAId
            return getMapping().isPrimaryKeyMapping() || getMapping().isJPAId();
        }
    }

    /**
     *  Can the attribute be null.
     *  @return boolean indicating whether or not the attribute can
     *          be null
     */
    @Override
    public boolean isOptional() {
        return getMapping().isOptional();
    }


    /**
     * INTERNAL:
     * Return whether the attribute is plural or singular
     */
    @Override
    public boolean isPlural() {
        return false;
    }

    /**
     *  Is the attribute a version attribute.
     *  @return boolean indicating whether or not attribute is
     *          a version attribute
     */
    @Override
    public boolean isVersion() {
        if (getDescriptor().usesOptimisticLocking() && getMapping().isDirectToFieldMapping()) {
            OptimisticLockingPolicy policy = getDescriptor().getOptimisticLockingPolicy();

            return policy.getWriteLockField().equals(getMapping().getField());
        }
        return false;
    }

    @Override
    public Bindable.BindableType getBindableType() {
        return Bindable.BindableType.SINGULAR_ATTRIBUTE;
    }

    /**
     *  Return the Java type of the represented attribute.
     *  @return Java type
     */
    @Override
    public Class<T> getJavaType() {
        if(null == elementType) {
            Class aJavaType = getMapping().getAttributeClassification();
            if(null == aJavaType) {
                aJavaType = getMapping().getField().getType();
                if(null == aJavaType) {
                    // lookup the attribute on the containing class
                    Class containingClass = getMapping().getDescriptor().getJavaClass();
                    Field aField = null;
                    try {
                        aField = containingClass.getDeclaredField(getMapping().getAttributeName());
                        aJavaType = aField.getType();
                        return aJavaType;
                    } catch (NoSuchFieldException nsfe) {
                        // This exception will be warned about below
                        if(null == aJavaType) {
                            AbstractSessionLog.getLog().log(SessionLog.FINEST, SessionLog.METAMODEL, "metamodel_attribute_class_type_is_null", this);
                            return (Class<T>) MetamodelImpl.DEFAULT_ELEMENT_TYPE_FOR_UNSUPPORTED_MAPPINGS;
                        }
                    }
                }
            }
            return aJavaType;
        } else {
            return this.elementType.getJavaType();
        }
    }

    /**
     * Return the type that represents the type of the attribute.
     * @return type of attribute
     */
    @Override
    public Type<T> getType() {
        return elementType;
    }

    /**
     * Return the String representation of the receiver.
     */
    @Override
    public String toString() {
        StringBuffer aBuffer = new StringBuffer("SingularAttributeImpl[");
        aBuffer.append(getType());
        aBuffer.append(",");
        aBuffer.append(getMapping());
        aBuffer.append("]");
        return aBuffer.toString();
    }
}
