/*
 * Copyright (c) 1998, 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
package org.eclipse.persistence.internal.jpa.parsing;

import java.security.AccessController;
import java.security.PrivilegedActionException;

import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.mappings.AggregateCollectionMapping;
import org.eclipse.persistence.mappings.AggregateMapping;
import org.eclipse.persistence.mappings.CollectionMapping;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.mappings.DirectCollectionMapping;
import org.eclipse.persistence.mappings.querykeys.ForeignReferenceQueryKey;
import org.eclipse.persistence.mappings.querykeys.QueryKey;
import org.eclipse.persistence.internal.queries.ContainerPolicy;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.internal.security.PrivilegedClassForName;
import org.eclipse.persistence.internal.helper.BasicTypeHelperImpl;

/**
 * INTERNAL
 * <p><b>Purpose</b>: Implement type helper methods specified by TypeHelper.
 * This implementation uses Class instances to represent a type.
 */
public class TypeHelperImpl
    extends BasicTypeHelperImpl implements TypeHelper {

    /** The session. */
    private final AbstractSession session;

    /** The class loader used to resolve type names. */
    private final ClassLoader classLoader;

    /** */
    public TypeHelperImpl(AbstractSession session, ClassLoader classLoader) {
        this.session = session;
        this.classLoader = classLoader;
    }

    /** Returns a type representation for the specified type name or null if
     * there is no such type.
     */
    @Override
    public Object resolveTypeName(String typeName) {
        try {
            if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                try {
                    return AccessController.doPrivileged(
                        new PrivilegedClassForName<>(typeName, true, classLoader));
                } catch (PrivilegedActionException exception) {
                    return null;
                }
            } else {
                return PrivilegedAccessHelper.getClassForName(typeName, true, classLoader);
            }
        } catch (ClassNotFoundException ex) {
            return null;
        }
    }

    /** Returns the type of the attribute with the specified name in the
     * specified owner class.
     */
    @Override
    public Object resolveAttribute(Object ownerClass, String attribute) {
        DatabaseMapping mapping = resolveAttributeMapping(ownerClass, attribute);
        if (mapping != null) {
            return getType(mapping);
        }
        QueryKey queryKey = resolveQueryKey(ownerClass, attribute);
        if (queryKey == null) {
            return null;
        } else if (queryKey.isForeignReferenceQueryKey()) {
            return ((ForeignReferenceQueryKey)queryKey).getReferenceClass();
        } else {
            return Object.class;
        }
    }

    /** Returns the type of the map key for the mapping on ownerClass named attribute
     * Returns null if that mapping does not exist or does not contain a map key
     */
    @Override
    public Object resolveMapKey(Object ownerClass, String attribute) {
        Object type = null;
        DatabaseMapping mapping = resolveAttributeMapping(ownerClass, attribute);
        if (mapping.isCollectionMapping()){
            ContainerPolicy cp = mapping.getContainerPolicy();
            type = cp.getKeyType();
        }
        return type;
    }

    /** Returns the type of the class corresponding to the specified abstract
     * schema type.
     */
    @Override
    public Object resolveSchema(String schemaName) {
        ClassDescriptor descriptor = session.getDescriptorForAlias(schemaName);
        return (descriptor != null) ? descriptor.getJavaClass() : null;
    }

    /** Returns the enum constant if the specified type denotes an enum type
     * and the specified constant denotes a constant of the enum type.
     */
    @Override
    public Object resolveEnumConstant(Object type, String constant) {
        Class clazz = getJavaClass(type);
        Object[] constants = clazz.getEnumConstants();
        if (constants != null) {
            for (int i = 0; i < constants.length; i++) {
                Enum<?> enumConstant = (Enum<?>) constants[i];
                if (enumConstant.name().equals(constant)) {
                   return enumConstant;
                }
            }
        }
        return null;
    }

    /** Returns true if the specified type denotes an entity class. */
    @Override
    public boolean isEntityClass(Object type) {
        ClassDescriptor desc = getDescriptor(type);
        return (desc != null) && !desc.isAggregateDescriptor();
    }

    /** Returns true if the specified type denotes an orderable type */
    @Override
    public boolean isOrderableType(Object type) {
        return !(isEntityClass(type) || isEmbeddable(type));
    }

    /** Returns true if the specified type denotes an embedded class. */
    @Override
    public boolean isEmbeddable(Object type) {
        ClassDescriptor desc = getDescriptor(type);
        return (desc != null) && desc.isAggregateDescriptor();
    }

    /** Returns true if the specified type denotes an embedded attribute. */
    @Override
    public boolean isEmbeddedAttribute(Object ownerClass, String attribute) {
        DatabaseMapping mapping =
            resolveAttributeMapping(ownerClass, attribute);
        return (mapping != null) && mapping.isAggregateObjectMapping();
    }

    /** Returns true if the specified type denotes a simple state attribute. */
    @Override
    public boolean isSimpleStateAttribute(Object ownerClass, String attribute) {
        DatabaseMapping mapping =
            resolveAttributeMapping(ownerClass, attribute);
        return (mapping != null) && mapping.isDirectToFieldMapping();
    }

    /** Returns true if the specified attribute denotes a single valued
     * or collection valued relationship attribute.
     */
    @Override
    public boolean isRelationship(Object ownerClass, String attribute) {
        DatabaseMapping mapping =
            resolveAttributeMapping(ownerClass, attribute);
        return (mapping != null) && mapping.isForeignReferenceMapping();
    }

    /** Returns true if the specified attribute denotes a single valued
     * relationship attribute.
     */
    @Override
    public boolean isSingleValuedRelationship(Object ownerClass,
                                              String attribute) {
        DatabaseMapping mapping =
            resolveAttributeMapping(ownerClass, attribute);
        return (mapping != null) && mapping.isObjectReferenceMapping();
    }

    /** Returns true if the specified attribute denotes a collection valued
     * relationship attribute.
     */
    @Override
    public boolean isCollectionValuedRelationship(Object ownerClass,
                                                  String attribute) {
        DatabaseMapping mapping =
            resolveAttributeMapping(ownerClass, attribute);
        return (mapping != null) &&
            (mapping.isOneToManyMapping() || mapping.isManyToManyMapping());
    }

    // ===== Internal helper methods =====

    /** Returns the class descriptor if the specified non-null type is a class
     * object.
     */
    private ClassDescriptor getDescriptor(Object type) {
        ClassDescriptor desc = null;
        if (type instanceof Class) {
            desc = session.getDescriptor((Class)type);
        } else if (type instanceof ClassDescriptor) {
            desc = (ClassDescriptor)type;
        }
        return desc;
    }

    /** Returns the mapping for the specified attribute of the specified
     * class. The method returns null if the class is not known or if the
     * class does not have an attribute of the specified name.
     */
    private DatabaseMapping resolveAttributeMapping(Object ownerClass, String attribute) {
        ClassDescriptor descriptor = getDescriptor(ownerClass);
        return (descriptor == null) ? null : descriptor.getObjectBuilder().getMappingForAttributeName(attribute);
    }

    @Override
    public QueryKey resolveQueryKey(Object ownerClass, String attribute) {
        ClassDescriptor descriptor = getDescriptor(ownerClass);
        if (descriptor == null) {
            return null;
        }
        return descriptor.getQueryKeyNamed(attribute);
    }

    private Object getType(DatabaseMapping mapping) {
        if (mapping == null) {
            return null;
        }
        Object type = null;
        if (mapping.isDirectCollectionMapping()){
            type = ((DirectCollectionMapping)mapping).getDirectField().getType();
            if (type == null){
                type = Object.class;
            }
        } else if (mapping.isAggregateCollectionMapping()) {
            // Return the ClassDescriptor as the type representation in case
            // of an embedded. This makes sure that any property or field
            // access of the embedded uses the correct mapping information and
            // not the shell of the descriptors as stored by the session.
            type = mapping.getReferenceDescriptor();
        } else if (mapping.isForeignReferenceMapping()) {
            ClassDescriptor descriptor = mapping.getReferenceDescriptor();
            type = descriptor == null ? null : descriptor.getJavaClass();
        } else if (mapping.isAggregateMapping()) {
            // Return the ClassDescriptor as the type representation in case
            // of an embedded. This makes sure that any property or field
            // access of the embedded uses the correct mapping information and
            // not the shell of the descriptors as stored by the session.
            type = mapping.getReferenceDescriptor();
        } else {
            type = mapping.getAttributeAccessor().getAttributeClass();
        }
        return type;
    }

}

