/*
 * 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)
//     07/06/2009-2.0  mobrien - 266912: Introduce IdentifiableTypeImpl between ManagedTypeImpl
//       - EntityTypeImpl now inherits from IdentifiableTypeImpl instead of ManagedTypeImpl
//       - MappedSuperclassTypeImpl now inherits from IdentifiableTypeImpl instead
//       of implementing IdentifiableType indirectly
//     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.HashMap;
import java.util.Map;

import jakarta.persistence.metamodel.MappedSuperclassType;

import org.eclipse.persistence.descriptors.ClassDescriptor;

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

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

    /**
     * INTERNAL:
     * The map of Identifiable types that inherit from this MappedSuperclass.
     * The scope of this map is outside of the JPA 2.0 specification and is limited to MappedSuperclass types.
     * The types in this map are keyed on the Java class of the inheriting type.
     * This map acts as the reverse of all superType fields that point to "this" MappedSuperclass.
     **/
    private Map<Class, IdentifiableTypeImpl> inheritingIdentifiableTypes;

    protected MappedSuperclassTypeImpl(MetamodelImpl metamodel, ClassDescriptor relationalDescriptor) {
        super(metamodel, relationalDescriptor);
        inheritingIdentifiableTypes = new HashMap<Class, IdentifiableTypeImpl>();
        // The supertype field will remain uninstantiated until MetamodelImpl.initialize() is complete
    }

    /**
     * INTERNAL:
     * Add an inheriting subclass to the map of Identifiable types that inherit from this mappedSuperclass.
     */
    protected void addInheritingType(IdentifiableTypeImpl identifiableType) {
        // The Map will always be instantiated in the constructor
        inheritingIdentifiableTypes.put(identifiableType.getJavaType(), identifiableType);
    }

    /**
     * INTERNAL:
     * Return an instance of a MappedSuperclassType based on the RelationalDescriptor.
     */
    protected static MappedSuperclassTypeImpl<?> create(MetamodelImpl metamodel, ClassDescriptor relationalDescriptor) {
        MappedSuperclassTypeImpl<?> mappedSuperclassTypeImpl = new MappedSuperclassTypeImpl(metamodel, relationalDescriptor);
        return mappedSuperclassTypeImpl;
    }

    /**
     * INTERNAL:
     *    MappedSuperclasses need special handling to get their type from an inheriting subclass.
     *    This function determines the type for an attribute by returning the same inherited attribute from a subclass
     */
    public AttributeImpl getMemberFromInheritingType(String name) {
        AttributeImpl inheritedAttribute = null;
        // search the inheriting types map for an attribute matching the attribute name
        for(IdentifiableTypeImpl inheritingType : inheritingIdentifiableTypes.values()) {
            //Entity types are initialized before MappedSuperclass types.  However, it is possible that the inheriting MappedSuperclass is not yet initialized.
            Map inheritingTypeMembers = inheritingType.getMembers();
            if ((null == inheritingTypeMembers) && inheritingType.isMappedSuperclass()) {
               //not initialized
               inheritingType.initialize();
               inheritingTypeMembers = inheritingType.getMembers();
            }

            if(inheritingTypeMembers != null && inheritingTypeMembers.containsKey(name)) {
               inheritedAttribute = (AttributeImpl)inheritingType.getAttribute(name);
               break;
            }
        }
        // we will return a null attribute in the case that a MappedSuperclass has no implementing entities
        return inheritedAttribute;
    }

    /**
     *  Return the persistence type.
     *  @return persistence type
     */
    @Override
    public jakarta.persistence.metamodel.Type.PersistenceType getPersistenceType() {
        return PersistenceType.MAPPED_SUPERCLASS;
    }

    @Override
    protected void initialize(){
        /**
         * Set the javaClass on the descriptor for the current classLoader (normally done in MetadataProject.addMetamodelMappedSuperclass).
         * This will ensure the class is both set and is in the right classLoader - even if the class is already set.
         * Perform this conversion only for our custom pseudo descriptors for MappedSuperclasses.
         * The classLoader should be obtained from the ConversionManager so we handle EE deployments using a shared-library
         */
        descriptor.convertClassNamesToClasses(metamodel.getSession().getDatasourcePlatform().getConversionManager().getLoader());
        super.initialize();
    }

    /**
     * INTERNAL:
     * Return whether this type is an Entity (true) or MappedSuperclass (false) or Embeddable (false)
     */
    @Override
    public boolean isEntity() {
        return false;
    }

    /**
     * INTERNAL:
     * Return whether this type is an MappedSuperclass (true) or Entity (false) or Embeddable (false)
     */
    @Override
    public boolean isMappedSuperclass() {
        return !isEntity();
    }
}
