/*
 * 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:
//     Oracle - initial API and implementation from Oracle TopLink
//     05/26/2009-2.0  mobrien - 266912: Add implementation of IdentifiableType
//       as EntityType inherits here instead of ManagedType as of rev# 4265
//     09/23/2009-2.0  mobrien - 266912: Implement hasSingleIdAttribute() and
//       all other 6 remaining methods for Id and Version support.
//       DI 71 - 77 and 56
//       http://wiki.eclipse.org/EclipseLink/Development/JPA_2.0/metamodel_api#DI_74:_20090909:_Implement_IdentifiableType.hasSingleIdAttribute.28.29
//     10/21/2009-2.0 Guy Pelletier
//       - 290567: mappedbyid support incomplete
//     06/14/2010-2.1  mobrien - 314906: getJavaType should return the
//       collection javaType C in <X,C,V) of <X, List<V>, V> instead off the elementType V.
//       Because of this we switch to using getBindableJavaType() in getIdType()
//     08/06/2010-2.2 mobrien 322018 - reduce protected instance variables to private to enforce encapsulation
package org.eclipse.persistence.internal.jpa.metamodel;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

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

import org.eclipse.persistence.descriptors.CMPPolicy;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.internal.helper.DatabaseField;
import org.eclipse.persistence.internal.localization.ExceptionLocalization;
import org.eclipse.persistence.mappings.DatabaseMapping;

/**
 * <p>
 * <b>Purpose</b>: Provides the implementation for the Entity 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 IdentifiableType represent entity or
 *  mapped superclass types.
 *
 * @see jakarta.persistence.metamodel.EntityType
 *
 * @since EclipseLink 1.2 - JPA 2.0
 * @param <X> The represented entity or mapped superclass type.
 *
 */
public abstract class IdentifiableTypeImpl<X> extends ManagedTypeImpl<X> implements IdentifiableType<X> {

    /**
     * The supertype may be an entity or mappedSuperclass.<p>
     * For top-level inheritance root identifiable types with no superclass - return null (not Object)
     */
    private IdentifiableType<? super X> superType;

    /**
     * The collection of SingularAttributes that are Id attributes.
     */
    private Set<SingularAttribute<? super X, ?>> idAttributes;

    /**
     * The SingularAttribute if it exists that is a version attribute
     */
    private SingularAttribute<? super X, ?> versionAttribute;

    protected IdentifiableTypeImpl(MetamodelImpl metamodel, ClassDescriptor descriptor) {
        super(metamodel, descriptor);
        /* The superType field cannot be set until all ManagedType instances
         * have been instantiated for this metamodel.
         * This is required so that any references between attributes can be resolved.
         * This occurs later in MetamodelImpl.initialize()
         * The idAttributes field is computed at the end of MetamodelImpl.initialize()
         * The versionAttribute is lazy loaded.
         */
    }

    /**
     * INTERNAL:
     * The idAttributes collection is computed at the end of MetamodelImpl.initialize()
     */
    protected void initializeIdAttributes() {
        // initialize the set of id attributes directly from the mapping
        idAttributes = new HashSet<SingularAttribute<? super X, ?>>();
        for(Attribute attribute : this.getAttributes()) {
            if(!((AttributeImpl)attribute).isPlural()) {
                if(((SingularAttribute)attribute).isId()) {
                    idAttributes.add((SingularAttribute)attribute);
                }
            }
        }
    }

    /**
     *  Return the attribute that corresponds to the id attribute
     *  declared by the entity or mapped superclass.
     *  @param type  the type of the represented declared id attribute
     *  @return declared id attribute
     *  @throws IllegalArgumentException if id attribute of the given
     *          type is not declared in the identifiable type or if
     *          the identifiable type has an id class
     */
    @Override
    public <Y> SingularAttribute<X, Y> getDeclaredId(Class<Y> type) {
        /**
         * We throw an IAE in 3 cases
         * 1) If the type is different from the javaType of the attribute
         * 2) If the id is not declared on (this) type
         * 3) If the id is not part of an IdClass (it is an EmbeddedId or just an Id)
         * 4) If the id does not exist on the hierarchy - never happens
         */
        // No need to check if an id exists - on an IdentifiableType - there is always at least one
        // This call will throw an IAE for 1) and 3)
        SingularAttribute<? super X, Y> anId = this.getId(type);
        // return the id only if it is declared on this IdentifableType
        // We know that the attribute exists - so the an IAE will be thrown for 2) for us
        return (SingularAttribute<X, Y>)getDeclaredAttribute(anId.getName(), true);
    }

    /**
     *  Return the attribute that corresponds to the version
     *  attribute declared by the entity or mapped superclass.
     *  @param type  the type of the represented declared version
     *               attribute
     *  @return declared version attribute
     *  @throws IllegalArgumentException if version attribute of the
     *          type is not declared in the identifiable type
     */
    @Override
    public <Y> SingularAttribute<X, Y> getDeclaredVersion(Class<Y> type) {
        /**
         * We throw an IAE in 3 cases
         * 1) If the type is different from the javaType of the attribute
         * 2) If the version is not declared on (this) type
         * 3) If the version does not exist on the hierarchy
         */
        // This call will throw an IAE for 1) and 3)
        SingularAttribute<? super X, Y> aVersion = this.getVersion(type);
        // return the version only if it is declared on this IdentifableType
        // We know that the attribute exists - so the an IAE will be thrown for 2) for us
        return (SingularAttribute<X, Y>)getDeclaredAttribute(aVersion.getName(), true);
    }

    /**
     *  Return the attributes corresponding to the id class of the
     *  identifiable type.
     *  @return id attributes
     *  @throws IllegalArgumentException if the identifiable type
     *          does not have an id class
     */
    @Override
    public Set<SingularAttribute<? super X, ?>> getIdClassAttributes() {
        // Get the list of IdClass attributes previously stored on the core project during metadata processing
        List<String> idClassNamesList = getMetamodel().getProject().getMetamodelIdClassMap()
            .get(getJavaType().getCanonicalName());
        // Check for IdClass existence
        if(null != idClassNamesList) {
            // All Id attributes are part of an IdClass
            return this.idAttributes;
        } else {
            // No IdClass attributes found - the IdentifiableType may still have a single @Id or an @EmbeddedId in this case
            throw new IllegalArgumentException(ExceptionLocalization.buildMessage(
                    "metamodel_identifiable_type_has_no_idclass_attribute",
                    new Object[] {this}));
        }
    }

    /**
     *  Return the attribute that corresponds to the id attribute of
     *  the entity or mapped superclass.
     *  @param type  the type of the represented id attribute
     *  @return id attribute
     *  @throws IllegalArgumentException if id attribute of the given
     *          type is not present in the identifiable type or if
     *          the identifiable type has an id class
     */
    @Override
    public <Y> SingularAttribute<? super X, Y> getId(Class<Y> type) {
        // We assume that there is at most a single EmbeddedId
        SingularAttribute<? super X, Y> idAttribute = null;
        if(!hasSingleIdAttribute()) {
            // Id is part of an IdClass
            throw new IllegalArgumentException(ExceptionLocalization.buildMessage(
                    "metamodel_identifiable_id_attribute_is_incorrect_idclass",
                    new Object[] { this }));
        } else {
            // verify single id attribute type
            for(SingularAttribute<? super X, ?> anAttribute : idAttributes) {
                // Verify type is correct - relax restriction on null and Object.class (from same classLoader)
                if(null == type || Object.class == type ||
                        type.getCanonicalName().equals(anAttribute.getJavaType().getCanonicalName())) {
                    idAttribute = (SingularAttribute<? super X, Y>) anAttribute;
                } else {
                    throw new IllegalArgumentException(ExceptionLocalization.buildMessage(
                        "metamodel_identifiable_id_attribute_type_incorrect",
                        new Object[] { anAttribute, this, type, anAttribute.getJavaType() }));
                }
            }
        }
        return idAttribute;
    }

    /**
     *  Return the type that represents the type of the id.
     *  @return type of id
     */
    @Override
    public Type<?> getIdType() {
        // NOTE: This code is another good reason to abstract out a PKPolicy on the descriptor
        CMPPolicy cmpPolicy = getDescriptor().getCMPPolicy();
        if (null == cmpPolicy) {
            // Composite key support (IE: @EmbeddedId)
            List<DatabaseMapping> pkMappings = getDescriptor().getObjectBuilder().getPrimaryKeyMappings();
            // Check the primaryKeyFields on the descriptor - for MappedSuperclass pseudo-Descriptors
            if(pkMappings.isEmpty()) {
                // Search the mappings for Id mappings
                for(DatabaseMapping aMapping : getDescriptor().getMappings()) {
                    if(aMapping.isJPAId()) {
                        // get the attribute Id (declared or not)
                        Attribute<X, ?> anAttribute = this.getAttribute(aMapping.getAttributeName());
                        if(anAttribute != null) {
                            return this.getMetamodel().getType(((Bindable)anAttribute).getBindableJavaType()); // all Attributes are Bindable
                        }
                    }
                }
            }

            if (pkMappings.size() == 1) {
                Class aClass = pkMappings.get(0).getAttributeClassification(); // null for OneToOneMapping
                // lookup class in our types map
                return this.getMetamodel().getType(aClass);
            }
        }

        // Single Key support using any Java class - built in or user defined
        // There already is an instance of the PKclass on the policy
        if (cmpPolicy != null && cmpPolicy.isCMP3Policy()) {
            // BasicType, EntityType or IdentifiableType are handled here, lookup the class in the types map and create a wrapper if it does not exist yet
            return this.getMetamodel().getType(cmpPolicy.getPKClass());
        }
        // Non-specification mandated exception
        throw new IllegalArgumentException(ExceptionLocalization.buildMessage(
                "metamodel_incompatible_persistence_config_for_getIdType",
                new Object[] { this }));
    }

    /**
     *  Return the identifiable type that corresponds to the most
     *  specific mapped superclass or entity extended by the entity
     *  or mapped superclass.
     *  @return supertype of identifiable type or null if no such supertype
     */
    @Override
    public IdentifiableType<? super X> getSupertype() {
        return this.superType;
    }

    /**
     *  Return the attribute that corresponds to the version
     *    attribute of the entity or mapped superclass.
     *  @param type  the type of the represented version attribute
     *  @return version attribute
     *  @throws IllegalArgumentException if version attribute of the
     *          given type is not present in the identifiable type
     */
    @Override
    public <Y> SingularAttribute<? super X, Y> getVersion(Class<Y> type) {
        // Lazy load the version attribute if it exists
        if(null == getVersion()) {
            // No version exists - throw IAE
            throw new IllegalArgumentException(ExceptionLocalization.buildMessage(
                "metamodel_identifiable_no_version_attribute_present",
                new Object[] { this }));
        } else {
            // Verify the type (Note: ClassLoaders do not have to be the same)
            // Relax restriction on null and Object.class (from same classLoader)
            if(null == type || Object.class == type ||
                    type.getCanonicalName().equals(versionAttribute.getJavaType().getCanonicalName())) {
                return (SingularAttribute<? super X, Y>)versionAttribute;
            } else {
                throw new IllegalArgumentException(ExceptionLocalization.buildMessage(
                    "metamodel_identifiable_version_attribute_type_incorrect",
                    new Object[] { versionAttribute, this, type, versionAttribute.getJavaType()}));
            }
        }
    }

    /**
     * INTERNAL:
     * Return the version attribute on this type.
     * If no version attribute exists - return null.
     */
    private <Y> SingularAttribute<? super X, ?> getVersion() {
        if(hasVersionAttribute()) {
            return versionAttribute;
        } else {
            return null;
        }
    }

    /**
     *  Whether or not the identifiable type has an id attribute.
     *  Returns true for a simple id or embedded id; returns false
     *  for an idclass.
     *  @return boolean indicating whether or not the identifiable
     *           type has a single id attribute
     */
    @Override
    public boolean hasSingleIdAttribute() {
        // The following section will return false for any multiple EmbeddableId as well as multiple Ids as part of an IdClass
        // Note: there will always be at least 1 Id for an IdentifiableType

        /**
         * Since we are in IdentifiableType which involves only Entities and MappedSuperclasses,
         * we are safe to assume that there will always be an Id of some sort - we are not in
         * Basic, Embeddable or transient types.
         * Check the core API project for any IdClass matching this IdentifiableType
         * after we check directly on the descriptor for an Id.
         *  References: SubQueryImpl.select()
         */

        // Note: this function will return false only if an IdClass is present
        List<DatabaseField> pkFields = this.getDescriptor().getPrimaryKeyFields();
        // return false for no Id field types
        if(pkFields.isEmpty()) {
            return false;
        } else {
            // Optional: Verify the mapping on the each field and whether it is an IdClass
            Class pkClass = null;
            if(this.getDescriptor().hasCMPPolicy()) {
                pkClass = this.getDescriptor().getCMPPolicy().getPKClass();
                if(null == pkClass) {
                    return false;
                }
            } else {
                // MappedSuperclass descriptors do not have a CMP policy yet because the are not initialized
                return pkFields.size() < 2;
            }

            // 288792: Search the values of the list of IdClass attribute names stored on the project
            for (List<String> idClassNamesList : getMetamodel().getProject().getMetamodelIdClassMap().values()) {
                for(String idClassName : idClassNamesList) {
                    if(idClassName.equals(pkClass.getCanonicalName())) {
                        return false;
                    }
                }
            }
        }
        return true;
    }

    /**
     *  Whether or not the identifiable type has a version attribute.
     *  @return boolean indicating whether or not the identifiable
     *           type has a version attribute
     */
    @Override
    public boolean hasVersionAttribute() {
        // The versionAttribute is lazy loaded
        if(null != versionAttribute) {
            return true;
        } else {
            for(Attribute attribute : this.getAttributes()) {
                if(!((AttributeImpl)attribute).isPlural() && ((SingularAttribute)attribute).isVersion()) {
                    versionAttribute = (SingularAttribute)attribute;
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * INTERNAL:
     * Return whether this type is identifiable.
     * This would be EntityType and MappedSuperclassType
     */
    @Override
    protected boolean isIdentifiableType() {
        return true;
    }

    /**
     * INTERNAL:
     * Set the superType for this IdentifiableType - only after all ManagedTypes
     * have been instantiated for this Metamodel.<p>
     * Top-level identifiable types have their supertype set to null.
     *
     * @param superType - the entity or mappedSuperclass superType
     */
    protected void setSupertype(IdentifiableType<? super X> superType) {
        // See design issue #42 - we return null for top-level types (with no superclass) as well as unset supertypes
        // http://wiki.eclipse.org/EclipseLink/Development/JPA_2.0/metamodel_api#DI_42:_20090709:_IdentifiableType.supertype_-_what_do_top-level_types_set_it_to
        this.superType = superType;
    }
}
