/*
 * Copyright (c) 2011, 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
//     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.jpa.CMP3Policy;
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 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(((CMP3Policy) 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.
     * @param <Y>
     * @return
     */
    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 = ((CMP3Policy)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
     * @return
     */
    @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;
    }
}
