/*
 * 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 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.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(final ValueHolderInterface<?> valueHolder) {
        try {
            IndirectContainer container = null;
            if (getContainerConstructor().getParameterTypes().length == 0) {
                container = PrivilegedAccessHelper.callDoPrivilegedWithException(
                        () -> (IndirectContainer)PrivilegedAccessHelper.invokeConstructor(getContainerConstructor(), new Object[0])
                );
                container.setValueHolder(valueHolder);
            } else {
                container = PrivilegedAccessHelper.callDoPrivilegedWithException(
                        () -> (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 {
            this.containerConstructor = PrivilegedAccessHelper.callDoPrivilegedWithException(
                    () -> PrivilegedAccessHelper.getConstructorFor(getContainerClass(), new Class<?>[] { ClassConstants.ValueHolderInterface_Class }, false)
            );
            return;
        // DO NOTHING, exception thrown at end
        } catch (NoSuchMethodException nsme) {
        // This indicates unexpected problem in the code
        } catch (Exception ex) {
            throw new RuntimeException(String.format(
                    "Invocation of %s constructior failed", getContainerClass().getName()), ex);
        }

        // Try to find the default constructor
        try {
            this.containerConstructor = PrivilegedAccessHelper.callDoPrivilegedWithException(
                    () -> PrivilegedAccessHelper.getConstructorFor(getContainerClass(), new Class<?>[0], false)
            );
            return;
        // DO NOTHING, exception thrown at end
        } catch (NoSuchMethodException nsme) {
        // This indicates unexpected problem in the code
        } catch (Exception ex) {
            throw new RuntimeException(String.format(
                    "Invocation of %s constructior failed", getContainerClass().getName()), ex);
        }
        // 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));
    }
}
