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

import java.lang.reflect.Constructor;
import java.security.AccessController;
import java.security.PrivilegedActionException;

import org.eclipse.persistence.exceptions.DescriptorException;
import org.eclipse.persistence.indirection.IndirectContainer;
import org.eclipse.persistence.indirection.ValueHolder;
import org.eclipse.persistence.indirection.ValueHolderInterface;
import org.eclipse.persistence.internal.descriptors.DescriptorIterator;
import org.eclipse.persistence.internal.helper.ClassConstants;
import org.eclipse.persistence.internal.identitymaps.CacheKey;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.internal.security.PrivilegedGetConstructorFor;
import org.eclipse.persistence.internal.security.PrivilegedInvokeConstructor;
import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.internal.sessions.UnitOfWorkImpl;
import org.eclipse.persistence.internal.sessions.remote.RemoteSessionController;
import org.eclipse.persistence.internal.sessions.remote.RemoteUnitOfWork;
import org.eclipse.persistence.queries.ObjectLevelReadQuery;
import org.eclipse.persistence.queries.ReadQuery;

/**
 * <b>Purpose</b>: Provide ability for developers to wrap ValueHolders (Basic Indirection)<p>
 * <b>Responsibilities</b>:<ul>
 * <li>Wrap &amp; un-wrap a ValueHolder within an IndirectContainer
 * <li>Reflectively instantiate the containers as required
 * </ul>
 * @see org.eclipse.persistence.indirection.IndirectContainer
 * @author Doug Clarke (TOP)
 * @since 2.5.0.5
 */
public class ContainerIndirectionPolicy extends BasicIndirectionPolicy {
    private Class containerClass;
    private String containerClassName;
    private transient Constructor containerConstructor;

    /**
     * INTERNAL:
     * Construct a new indirection policy.
     */
    public ContainerIndirectionPolicy() {
        super();
    }

    /**
     * INTERNAL:
     *    Return a backup clone of the attribute.
     */
    @Override
    public Object backupCloneAttribute(Object attributeValue, Object clone, Object backup, UnitOfWorkImpl unitOfWork) {
        IndirectContainer container = (IndirectContainer)attributeValue;
        ValueHolderInterface valueHolder = container.getValueHolder();
        ValueHolderInterface newValueHolder = (ValueHolderInterface)super.backupCloneAttribute(valueHolder, clone, backup, unitOfWork);
        return buildContainer(newValueHolder);
    }

    /**
     * Build a container with the initialized constructor.
     */
    protected IndirectContainer buildContainer(ValueHolderInterface valueHolder) {
        try {
            IndirectContainer container = null;
            if (getContainerConstructor().getParameterTypes().length == 0) {
                if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                    container = (IndirectContainer)AccessController.doPrivileged(new PrivilegedInvokeConstructor(getContainerConstructor(), new Object[0]));
                }else{
                    container = (IndirectContainer)PrivilegedAccessHelper.invokeConstructor(getContainerConstructor(), new Object[0]);
                }
                container.setValueHolder(valueHolder);
            } else {
                if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                    container = (IndirectContainer)AccessController.doPrivileged(new PrivilegedInvokeConstructor(getContainerConstructor(), new Object[] { valueHolder }));
                }else{
                    container = (IndirectContainer)PrivilegedAccessHelper.invokeConstructor(getContainerConstructor(), new Object[] { valueHolder });
                }
            }
            return container;
        } catch (Exception exception) {
            throw DescriptorException.invalidIndirectionPolicyOperation(this, "buildContainer constructor (" + getContainerConstructor() + ") Failed: " + exception);
        }
    }

    /**
     * INTERNAL: This method can be used when an Indirection Object is required
     * to be built from a provided ValueHolderInterface object. This may be used
     * for custom value holder types. Certain policies like the
     * TransparentIndirectionPolicy may wrap the valueholder in another object.
     */

    @Override
    public Object buildIndirectObject(ValueHolderInterface valueHolder){
        return buildContainer(valueHolder);
    }

    /**
     * INTERNAL:
     *    Return a clone of the attribute.
     *  @param buildDirectlyFromRow indicates that we are building the clone directly
     *  from a row as opposed to building the original from the row, putting it in
     *  the shared cache, and then cloning the original.
     */
    @Override
    public Object cloneAttribute(Object attributeValue, Object original, CacheKey cacheKey, Object clone, Integer refreshCascade, AbstractSession cloningSession, boolean buildDirectlyFromRow) {
        IndirectContainer container = (IndirectContainer)attributeValue;
        ValueHolderInterface valueHolder = container.getValueHolder();
        ValueHolderInterface newValueHolder = (ValueHolderInterface)super.cloneAttribute(valueHolder, original, cacheKey, clone, refreshCascade, cloningSession, buildDirectlyFromRow);

        return buildContainer(newValueHolder);
    }

    /**
     * INTERNAL:
     *    Return the reference row for the reference object.
     * This allows the new row to be built without instantiating
     * the reference object.
     * Return null if the object has already been instantiated.
     */
    @Override
    public AbstractRecord extractReferenceRow(Object referenceObject) {
        if (this.objectIsInstantiated(referenceObject)) {
            return null;
        } else {
            return ((DatabaseValueHolder)((IndirectContainer)referenceObject).getValueHolder()).getRow();
        }
    }

    /**
     * Returns the Container class which implements IndirectContainer.
     */
    public Class getContainerClass() {
        return containerClass;
    }

    /**
     * INTERNAL:
     * Used by MW.
     */
    public String getContainerClassName() {
        if ((containerClassName == null) && (containerClass != null)) {
            containerClassName = containerClass.getName();
        }
        return containerClassName;
    }

    /**
     *
     * @return java.lang.reflect.Constructor
     */
    protected Constructor getContainerConstructor() {
        return containerConstructor;
    }

    /**
     * INTERNAL:
     *    Return the original indirection object for a unit of work indirection object.
     */
    @Override
    public Object getOriginalIndirectionObject(Object unitOfWorkIndirectionObject, AbstractSession session) {
        IndirectContainer container = (IndirectContainer)unitOfWorkIndirectionObject;
        if (container.getValueHolder() instanceof UnitOfWorkValueHolder) {
            ValueHolderInterface<?> valueHolder = ((UnitOfWorkValueHolder)container.getValueHolder()).getWrappedValueHolder();
            if ((valueHolder == null) && session.isRemoteUnitOfWork()) {
                RemoteSessionController controller = ((RemoteUnitOfWork)session).getParentSessionController();
                valueHolder = controller.getRemoteValueHolders().get(((UnitOfWorkValueHolder)container.getValueHolder()).getWrappedValueHolderRemoteID());
            }
            return buildContainer(valueHolder);
        } else {
            return container;
        }
    }

    /**
     * INTERNAL:
     *    Return the original indirection object for a unit of work indirection object.
     */
    @Override
    public Object getOriginalIndirectionObjectForMerge(Object unitOfWorkIndirectionObject, AbstractSession session) {
        IndirectContainer container = (IndirectContainer) getOriginalIndirectionObject(unitOfWorkIndirectionObject, session);
        DatabaseValueHolder holder = (DatabaseValueHolder)container.getValueHolder();
        if (holder != null && holder.getSession()!= null){
            holder.setSession(session);
        }
        return container;
    }


    /**
     * INTERNAL:
     * Return the "real" attribute value, as opposed to any wrapper.
     * This will trigger the wrapper to instantiate the value.
     */
    @Override
    public Object getRealAttributeValueFromObject(Object object, Object attribute) {
        return ((IndirectContainer)attribute).getValueHolder().getValue();
    }

    /**
     * INTERNAL:
     * Ensure the container class implements IndirectContainer and that it
     * has a constructor which can be used.
     */
    @Override
    public void initialize() {
        // Verify that the provided class implements IndirectContainer
        if (!ClassConstants.IndirectContainer_Class.isAssignableFrom(containerClass)) {
            throw DescriptorException.invalidIndirectionContainerClass(this, containerClass);
        }

        // Try to find constructor which takes a ValueHolderInterface
        try {
            if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                try{
                    this.containerConstructor = AccessController.doPrivileged(new PrivilegedGetConstructorFor<Class<?>>(getContainerClass(), new Class[] { ClassConstants.ValueHolderInterface_Class }, false));
                }catch (PrivilegedActionException ex){
                    if (ex.getCause() instanceof NoSuchMethodException){
                        throw (NoSuchMethodException) ex.getCause();
                    }
                    throw (RuntimeException)ex.getCause();
                }
            }else{
                this.containerConstructor = PrivilegedAccessHelper.getConstructorFor(getContainerClass(), new Class[] { ClassConstants.ValueHolderInterface_Class }, false);
            }
            return;
        } catch (NoSuchMethodException nsme) {// DO NOTHING, exception thrown at end
        }

        // Try to find the default constructor
        try {
            if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                try{
                    this.containerConstructor = AccessController.doPrivileged(new PrivilegedGetConstructorFor<Class<?>>(getContainerClass(), new Class[0], false));
                }catch (PrivilegedActionException ex){
                    if (ex.getCause() instanceof NoSuchMethodException){
                        throw (NoSuchMethodException) ex.getCause();
                    }
                    throw (RuntimeException)ex.getCause();
                }
            }else{
                this.containerConstructor = PrivilegedAccessHelper.getConstructorFor(getContainerClass(), new Class[0], false);
            }
            return;
        } catch (NoSuchMethodException nsme) {// DO NOTHING, exception thrown at end
        }

        // If no constructor is found then we throw an initialization exception
        throw DescriptorException.noConstructorIndirectionContainerClass(this, containerClass);
    }

    /**
     * INTERNAL:
     * The method validateAttributeOfInstantiatedObject(Object attributeValue) fixes the value of the attributeValue
     * in cases where it is null and indirection requires that it contain some specific data structure.  Return whether this will happen.
     * This method is used to help determine if indirection has been triggered
     * @see validateAttributeOfInstantiatedObject(Object attributeValue)
     */
    @Override
    public boolean isAttributeValueFullyBuilt(Object attributeValue){
        return true;
    }


    /**
     * INTERNAL:
     *    Iterate over the specified attribute value,
     */
    @Override
    public void iterateOnAttributeValue(DescriptorIterator iterator, Object attributeValue) {
        super.iterateOnAttributeValue(iterator, ((IndirectContainer)attributeValue).getValueHolder());
    }

    /**
     * INTERNAL:
     *    Return the null value of the appropriate attribute. That is, the
     * field from the database is NULL, return what should be
     * placed in the object's attribute as a result.
     * In this case, return an empty ValueHolder.
     */
    @Override
    public Object nullValueFromRow() {
        return buildContainer(new ValueHolder());
    }

    /**
     * Reset the wrapper used to store the value.
     */
    @Override
    public void reset(Object target) {
        getMapping().setAttributeValueInObject(target, buildContainer(new ValueHolder()));
    }

    /**
     * INTERNAL:
     * Return whether the specified object is instantiated.
     */
    @Override
    public boolean objectIsInstantiated(Object object) {
        return ((IndirectContainer)object).getValueHolder().isInstantiated();
    }

    /**
     * INTERNAL:
     * Return whether the specified object can be instantiated without database access.
     */
    @Override
    public boolean objectIsEasilyInstantiated(Object object) {
        ValueHolderInterface valueHolder = ((IndirectContainer)object).getValueHolder();
        if (valueHolder instanceof DatabaseValueHolder) {
            return ((DatabaseValueHolder)valueHolder).isEasilyInstantiated();
        } else {
            return true;
        }
    }

    /**
     * Sets the Container class which implements IndirectContainer
     */
    public void setContainerClass(Class containerClass) {
        this.containerClass = containerClass;
    }

    /**
     * Set the container classname for the MW
     */
    public void setContainterClassName(String containerClassName) {
        this.containerClassName = containerClassName;
    }

    /**
     * INTERNAL:
     *    Set the value of the appropriate attribute of target to attributeValue.
     * In this case, place the value inside the target's ValueHolder.
     */
    @Override
    public void setRealAttributeValueInObject(Object target, Object attributeValue) {
        IndirectContainer container = (IndirectContainer)this.getMapping().getAttributeValueFromObject(target);
        container.getValueHolder().setValue(attributeValue);
        this.getMapping().setAttributeValueInObject(target, container);
    }

    /**
     * INTERNAL:
     * Return whether the type is appropriate for the indirection policy.
     * In this case, the type must either be assignable from IndirectContainer or
     * allow the conatinerClass to be assigned to it.
     */
    @Override
    protected boolean typeIsValid(Class attributeType) {
        return ClassConstants.IndirectContainer_Class.isAssignableFrom(attributeType) || attributeType.isAssignableFrom(getContainerClass());
    }

    /**
     * INTERNAL:
     *    Verify that the value of the attribute within an instantiated object
     * is of the appropriate type for the indirection policy.
     * In this case, the attribute must be non-null and it must be a
     * ValueHolderInterface.
     */
    @Override
    public Object validateAttributeOfInstantiatedObject(Object attributeValue) {
        if (!(getContainerClass().isInstance(attributeValue))) {
            throw DescriptorException.valueHolderInstantiationMismatch(attributeValue, this.getMapping());
        }
        return attributeValue;
    }

    /**
     * INTERNAL:
     * Return the value to be stored in the object's attribute.
     *    This value is determined by the batchQuery.
     * In this case, wrap the query in a ValueHolder for later invocation.
     */
    @Override
    public Object valueFromBatchQuery(ReadQuery batchQuery, AbstractRecord row, ObjectLevelReadQuery originalQuery, CacheKey parentCacheKey) {
        ValueHolderInterface valueHolder = (ValueHolderInterface)super.valueFromBatchQuery(batchQuery, row, originalQuery, parentCacheKey);
        return buildContainer(valueHolder);
    }

    /**
     * INTERNAL:
     * Return the value to be stored in the object's attribute.
     * This value is determined by invoking the appropriate
     * method on the object and passing it the row and session.
     * In this case, wrap the row in a ValueHolder for later use.
     */
    @Override
    public Object valueFromMethod(Object object, AbstractRecord row, AbstractSession session) {
        ValueHolderInterface valueHolder = (ValueHolderInterface)super.valueFromMethod(object, row, session);
        return buildContainer(valueHolder);
    }

    /**
     * INTERNAL:
     * Return the value to be stored in the object's attribute.
     *    This value is determined by the query.
     * In this case, wrap the query in a ValueHolder for later invocation.
     */
    @Override
    public Object valueFromQuery(ReadQuery query, AbstractRecord row, AbstractSession session) {
        ValueHolderInterface valueHolder = (ValueHolderInterface)super.valueFromQuery(query, row, session);
        return buildContainer(valueHolder);
    }

    /**
     * INTERNAL:
     * Return the value to be stored in the object's attribute.
     *    This value is determined by the row.
     * In this case, simply wrap the object in a ValueHolder.
     */
    @Override
    public Object valueFromRow(Object object) {
        return buildContainer(new ValueHolder(object));
    }
}
