/*
 * 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.descriptors;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.persistence.exceptions.DatabaseException;
import org.eclipse.persistence.exceptions.DescriptorException;
import org.eclipse.persistence.exceptions.QueryException;
import org.eclipse.persistence.exceptions.ValidationException;
import org.eclipse.persistence.expressions.Expression;
import org.eclipse.persistence.internal.queries.ContainerPolicy;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.queries.ComplexQueryResult;
import org.eclipse.persistence.queries.ObjectLevelReadQuery;
import org.eclipse.persistence.queries.ReadAllQuery;
import org.eclipse.persistence.queries.ReadObjectQuery;

/**
 * <b>Purpose</b>: Allows for a descriptor's implemented interfaces to be configured.
 * Generally Interface Descriptors are used for 1 of 2 reasons:<p>
 *      a. Interface descriptors can be used to query across a set of classes that do not share a table.<br>
 *      b. As a target of a variable one to one mapping.
 *
 * @since TopLink for Java 2.0
 */
public class InterfacePolicy implements Serializable, Cloneable {
    protected List<Class<?>> parentInterfaces;
    protected List<String> parentInterfaceNames;
    protected List<ClassDescriptor> parentDescriptors;
    protected List<ClassDescriptor> childDescriptors;
    protected ClassDescriptor descriptor;
    protected Class<?> implementorDescriptor;
    protected String implementorDescriptorClassName;

    /**
     * INTERNAL:
     * Create a new policy.
     * Only descriptor involved in interface should have a policy.
     */
    public InterfacePolicy() {
        this.childDescriptors = new ArrayList<>();
        this.parentInterfaces = new ArrayList<>(2);
        this.parentInterfaceNames = new ArrayList<>(2);
        this.parentDescriptors = new ArrayList<>(2);
    }

    /**
     * INTERNAL:
     * Create a new policy.
     * Only descriptor involved in interface should have a policy.
     */
    public InterfacePolicy(ClassDescriptor descriptor) {
        this();
        this.descriptor = descriptor;
    }

    /**
     * INTERNAL:
     * Add child descriptor to the parent descriptor.
     */
    public void addChildDescriptor(ClassDescriptor childDescriptor) {
        getChildDescriptors().add(childDescriptor);
    }

    /**
     * INTERNAL:
     * Add parent descriptor.
     */
    public void addParentDescriptor(ClassDescriptor parentDescriptor) {
        getParentDescriptors().add(parentDescriptor);
    }

    /**
     * PUBLIC:
     * Add the parent Interface class.
     *
     * This method should be called once for each parent Interface of the Descriptor.
     */
    public void addParentInterface(Class<?> parentInterface) {
        getParentInterfaces().add(parentInterface);
    }

    public void addParentInterfaceName(String parentInterfaceName) {
        getParentInterfaceNames().add(parentInterfaceName);
    }

    /**
     * INTERNAL:
     * Return if there are any child descriptors.
     */
    public boolean hasChild() {
        return this.childDescriptors.size() > 0;
    }

    /**
     * INTERNAL:
     * Return all the child descriptors.
     */
    public List<ClassDescriptor> getChildDescriptors() {
        return childDescriptors;
    }

    protected ClassDescriptor getDescriptor() {
        return descriptor;
    }

    /**
     * INTERNAL:
     * Returns the implementor descriptor class.
     */
    @SuppressWarnings({"unchecked"})
    public <T> Class<T> getImplementorDescriptor() {
        return (Class<T>) implementorDescriptor;
    }

    /**
     * INTERNAL:
     * Returns the implementor descriptor class name.
     */
    public String getImplementorDescriptorClassName() {
        if ((implementorDescriptorClassName == null) && (implementorDescriptor != null)) {
            implementorDescriptorClassName = implementorDescriptor.getName();
        }
        return implementorDescriptorClassName;
    }

    /**
     * INTERNAL:
     * Return all the parent descriptors.
     */
    public List<ClassDescriptor> getParentDescriptors() {
        return parentDescriptors;
    }

    /**
     * INTERNAL:
     * Return the list of parent interfaces.
     */
    public List<Class<?>> getParentInterfaces() {
        return parentInterfaces;
    }

    public List<String> getParentInterfaceNames() {
        if (parentInterfaceNames.isEmpty() && !parentInterfaces.isEmpty()) {
            for (int i = 0; i < parentInterfaces.size(); i++) {
                parentInterfaceNames.add(parentInterfaces.get(i).getName());
            }
        }
        return parentInterfaceNames;
    }

    /**
     * INTERNAL:
     * Convert all the class-name-based settings in this InheritancePolicy to actual class-based settings.
     * This method is used when converting a project that has been built with class names to a project with classes.
     * It will also convert referenced classes to the versions of the classes from the classLoader.
     */
    public void convertClassNamesToClasses(ClassLoader classLoader) {
        List<Class<?>> newParentInterfaces = new ArrayList<>(2);
        for (Iterator<String> iterator = getParentInterfaceNames().iterator(); iterator.hasNext(); ) {
            String interfaceName = iterator.next();
            Class<?> interfaceClass = null;
            newParentInterfaces.add(PrivilegedAccessHelper.callDoPrivilegedWithException(
                    () -> PrivilegedAccessHelper.getClassForName(interfaceName, true, classLoader),
                    (ex) -> ValidationException.classNotFoundWhileConvertingClassNames(interfaceName, ex)
            ));
        }
        this.parentInterfaces = newParentInterfaces;
    }

    /**
     * INTERNAL:
     * Set the vector to store parent interfaces.
     */
    public void initialize(AbstractSession session) {
    }

    /**
     * INTERNAL:
     * Check if it is a child descriptor.
     */
    public boolean isInterfaceChildDescriptor() {
        return ((!(parentInterfaces == null) && !parentInterfaces.isEmpty()) ||
            (!(parentInterfaceNames == null) && !parentInterfaceNames.isEmpty()));
    }

    /**
     * INTERNAL:
     */
    public boolean isTablePerClassPolicy() {
        return false;
    }

    /**
     * INTERNAL:
     * Select all objects for a concrete descriptor.
     */
    protected Object selectAllObjects(ReadAllQuery query) {
        ReadAllQuery concreteQuery = (ReadAllQuery)prepareQuery(query);
        return query.getSession().executeQuery(concreteQuery, query.getTranslationRow());
    }

    /**
     * INTERNAL:
     * Select all objects for a concrete descriptor.
     */
    protected ObjectLevelReadQuery prepareQuery(ObjectLevelReadQuery query) {
        ObjectLevelReadQuery concreteQuery = null;
        Class<?> javaClass = this.descriptor.getJavaClass();
        // PERF: First check the subclass query cache for the prepared query.
        boolean shouldPrepare = query.shouldPrepare();
        if (shouldPrepare) {
            concreteQuery = (ObjectLevelReadQuery)query.getConcreteSubclassQueries().get(javaClass);
        }
        if (concreteQuery == null) {
            concreteQuery = (ObjectLevelReadQuery)query.deepClone();
            concreteQuery.setReferenceClass(javaClass);
            concreteQuery.setDescriptor(this.descriptor);
            // Disable query cache from implementation queries.
            concreteQuery.setQueryResultsCachePolicy(null);
            concreteQuery.getExpressionBuilder().setQueryClassAndDescriptor(javaClass, this.descriptor);

            // Update the selection criteria if needed as well and don't lose
            // the translation row.
            if (concreteQuery.getQueryMechanism().getSelectionCriteria() != null) {
                //make sure query builder is used for the selection criteria as deepClone will create
                //two separate builders.
                concreteQuery.getExpressionBuilder().setSession(query.getSession().getRootSession(concreteQuery));
                concreteQuery.setSelectionCriteria(concreteQuery.getQueryMechanism().getSelectionCriteria().rebuildOn(concreteQuery.getExpressionBuilder()));
            }
            if (concreteQuery.hasAdditionalFields()) {
                List<Object> rebuiltFields = new ArrayList<>(concreteQuery.getAdditionalFields().size());
                for (Object field : concreteQuery.getAdditionalFields()) {
                    if (field instanceof Expression) {
                        rebuiltFields.add(((Expression)field).rebuildOn(concreteQuery.getExpressionBuilder()));
                    } else {
                        rebuiltFields.add(field);
                    }
                }
                concreteQuery.setAdditionalFields(rebuiltFields);
            }
            if (shouldPrepare) {
                concreteQuery.setTranslationRow(null);
                if (concreteQuery.isReadObjectQuery()) {
                    ((ReadObjectQuery)concreteQuery).clearSelectionId();
                }
                concreteQuery.checkPrepare(query.getSession(), query.getTranslationRow());
                query.getConcreteSubclassQueries().put(javaClass, concreteQuery);
                concreteQuery = (ObjectLevelReadQuery)concreteQuery.clone();
                concreteQuery.setTranslationRow(query.getTranslationRow());
            }
            concreteQuery.setIsExecutionClone(true);
        } else {
            concreteQuery = (ObjectLevelReadQuery)concreteQuery.clone();
            concreteQuery.setIsExecutionClone(true);
            concreteQuery.setTranslationRow(query.getTranslationRow());
        }

        return concreteQuery;
    }

    /**
     * INTERNAL:
     * Select all objects for an interface descriptor.
     * This is accomplished by selecting for all of the concrete classes and then merging the objects.
     */
    public Object selectAllObjectsUsingMultipleTableSubclassRead(ReadAllQuery query) throws DatabaseException {
        ContainerPolicy containerPolicy = query.getContainerPolicy();
        Object objects = containerPolicy.containerInstance();
        if (query.shouldIncludeData()) {
            ComplexQueryResult result = new ComplexQueryResult();
            result.setResult(objects);
            result.setData(new ArrayList());
            objects = result;
        }
        int size = this.childDescriptors.size();
        for (int index = 0; index < size; index++) {
            ClassDescriptor descriptor = this.childDescriptors.get(index);
            objects = containerPolicy.concatenateContainers(
                    objects, descriptor.getInterfacePolicy().selectAllObjects(query), query.getSession());
        }

        return objects;
    }

    /**
     * INTERNAL:
     * Select one object of any concrete subclass.
     */
    protected Object selectOneObject(ReadObjectQuery query) throws DescriptorException {
        ReadObjectQuery concreteQuery = (ReadObjectQuery)prepareQuery(query);
        return query.getSession().executeQuery(concreteQuery, concreteQuery.getTranslationRow());
    }

    /**
     * INTERNAL:
     * Select one object of any concrete subclass.
     */
    public Object selectOneObjectUsingMultipleTableSubclassRead(ReadObjectQuery query) throws DatabaseException, QueryException {
        int size = this.childDescriptors.size();
        for (int index = 0; index < size; index++) {
            ClassDescriptor descriptor = this.childDescriptors.get(index);
            Object object = descriptor.getInterfacePolicy().selectOneObject(query);
            if (object != null) {
                return object;
            }
        }

        return null;
    }

    /**
     * INTERNAL:
     * Set the descriptor.
     */
    public void setDescriptor(ClassDescriptor descriptor) {
        this.descriptor = descriptor;
    }

    /**
     * INTERNAL:
     * Sets the implementor descriptor class.
     */
    public void setImplementorDescriptor(Class<?> implementorDescriptor) {
        this.implementorDescriptor = implementorDescriptor;
    }

    /**
     * INTERNAL:
     * Sets the implementor descriptor class name.
     */
    public void setImplementorDescriptorClassName(String implementorDescriptorClassName) {
        this.implementorDescriptorClassName = implementorDescriptorClassName;
    }

    /**
     * Set the Vector to store parent interfaces.
     */
    public void setParentInterfaces(List<Class<?>> parentInterfaces) {
        this.parentInterfaces = parentInterfaces;
    }

    public void setParentInterfaceNames(List<String> parentInterfaceNames) {
        this.parentInterfaceNames = parentInterfaceNames;
    }

    /**
     * INTERNAL:
     * Returns true if this descriptor should be ignored and the implementing
     * descriptor should be used instead.
     */
    public boolean usesImplementorDescriptor() {
        return (implementorDescriptor != null);
    }
}
