/*
 * 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.Proxy;
import java.security.AccessController;

import org.eclipse.persistence.internal.descriptors.DescriptorIterator;
import org.eclipse.persistence.internal.identitymaps.CacheKey;

import java.util.*;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.internal.security.PrivilegedNewInstanceFromClass;
import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.internal.sessions.MergeManager;
import org.eclipse.persistence.internal.sessions.UnitOfWorkImpl;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.exceptions.DescriptorException;
import org.eclipse.persistence.exceptions.IntegrityChecker;
import org.eclipse.persistence.indirection.ValueHolder;
import org.eclipse.persistence.indirection.ValueHolderInterface;
import org.eclipse.persistence.queries.ReadQuery;
import org.eclipse.persistence.queries.ObjectLevelReadQuery;
import org.eclipse.persistence.sessions.remote.DistributedSession;
import org.eclipse.persistence.internal.sessions.remote.*;

/**
 * <h2>ProxyIndirectionPolicy</h2>
 *
 * <p>Define the behavior for Proxy Indirection.</p>
 *
 * <p>Proxy Indirection uses the <CODE>Proxy</CODE> and <CODE>InvocationHandler</CODE> features
 * of JDK 1.3 to provide "transparent indirection" for 1:1 relationships.  In order to use Proxy
 * Indirection:</p>
 *
 * <ul>
 *        <li>The target class must implement at least one public interface</li>
 *        <li>The attribute on the source class must be typed as that public interface</li>
 * </ul>
 *
 * In this policy, proxy objects are returned during object creation.  When a message other than
 * <CODE>toString</CODE> is called on the proxy the real object data is retrieved from the database.
 *
 * @see            org.eclipse.persistence.internal.indirection.ProxyIndirectionHandler
 * @author        Rick Barkhouse
 * @since        TopLink 3.0
 */
public class ProxyIndirectionPolicy extends BasicIndirectionPolicy {
    private final Class<?>[] targetInterfaces;

    public ProxyIndirectionPolicy(Class<?>[] targetInterfaces) {
        this.targetInterfaces = targetInterfaces;
    }

    public ProxyIndirectionPolicy() {
        this.targetInterfaces = new Class<?>[] {  };
    }

    /**
     * INTERNAL:
     * Nothing required.
     */
    @Override
    public void initialize() {
        // Nothing required
    }

    /**
     * Reset the wrapper used to store the value.
     */
    @Override
    public void reset(Object target) {
        // Nothing required.
    }

    /**
     * INTERNAL:
     * Return if targetInterfaces is not empty.
     */
    public boolean hasTargetInterfaces() {
        return (targetInterfaces != null) && (targetInterfaces.length != 0);
    }

    /**
     * INTERNAL:
     * Return the value to be stored in the object's attribute.
     * This will be a proxy object.
     */
    @Override
    public Object valueFromRow(Object object) {
        ValueHolderInterface<?> valueHolder = new ValueHolder<>(object);

        return ProxyIndirectionHandler.newProxyInstance(object.getClass(), targetInterfaces, valueHolder);
    }

    /**
     * INTERNAL:
     * Return the value to be stored in the object's attribute.
     * This will be a proxy object.
     */
    @Override
    public Object valueFromQuery(ReadQuery query, AbstractRecord row, AbstractSession session) {
        ClassDescriptor descriptor = null;
        try {
            // Need an instance of the implementing class
            //CR#3838
            descriptor = session.getDescriptor(query.getReferenceClass());
            if (descriptor.isDescriptorForInterface()) {
                descriptor = descriptor.getInterfacePolicy().getChildDescriptors().get(0);
            }
        } catch (Exception e) {
            return null;
        }
        ValueHolderInterface<?> valueHolder = new QueryBasedValueHolder<>(query, row, session);

        return ProxyIndirectionHandler.newProxyInstance(descriptor.getJavaClass(), targetInterfaces, 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.
     */
    @Override
    public Object valueFromMethod(Object object, AbstractRecord row, AbstractSession session) {
        ValueHolderInterface<?> valueHolder = new TransformerBasedValueHolder<>(this.getTransformationMapping().getAttributeTransformer(), object, row, session);

        return ProxyIndirectionHandler.newProxyInstance(object.getClass(), targetInterfaces, valueHolder);
    }

    /**
     * INTERNAL:
     * Return the value to be stored in the object's attribute.
     * This value is determined by the batch query.     *
     * NOTE: Currently not supported anyway.
     */
    @Override
    public Object valueFromBatchQuery(ReadQuery batchQuery, AbstractRecord row, ObjectLevelReadQuery originalQuery, CacheKey parentCacheKey) {
        Object object;

        try {
            // Need an instance of the implementing class
            ClassDescriptor d = originalQuery.getDescriptor();
            if (d.isDescriptorForInterface()) {
                d = originalQuery.getDescriptor().getInterfacePolicy().getChildDescriptors().get(0);
            }
            if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()){
                object = AccessController.doPrivileged(new PrivilegedNewInstanceFromClass<>(d.getJavaClass()));
            }else{
                object = PrivilegedAccessHelper.newInstanceFromClass(d.getJavaClass());
            }
        } catch (Exception e) {
            //org.eclipse.persistence.internal.helper.Helper.toDo("*** Should probably throw some sort of TopLink exception here. ***");
            e.printStackTrace();
            return null;
        }
        ValueHolderInterface<?> valueHolder = new BatchValueHolder<>(batchQuery, row, this.getForeignReferenceMapping(), originalQuery, parentCacheKey);

        return ProxyIndirectionHandler.newProxyInstance(object.getClass(), targetInterfaces, valueHolder);
    }

    /**
     * INTERNAL:
     * Return whether the specified object is instantiated.
     */
    @Override
    public boolean objectIsInstantiated(Object object) {
        if (object instanceof Proxy) {
            ProxyIndirectionHandler<?> handler = (ProxyIndirectionHandler<?>)Proxy.getInvocationHandler(object);
            ValueHolderInterface<?> valueHolder = handler.getValueHolder();
            return valueHolder.isInstantiated();
        } else {
            return true;
        }
    }

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

    /**
     * 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.
     */
    @Override
    public Object nullValueFromRow() {
        return null;
    }

    /**
     * INTERNAL:
     * Replace the client value holder with the server value holder after copying some of the settings from
     * the client value holder.
     */
    @Override
    public void mergeRemoteValueHolder(Object clientSideDomainObject, Object serverSideDomainObject, MergeManager mergeManager) {
        getMapping().setAttributeValueInObject(clientSideDomainObject, serverSideDomainObject);
    }

    /**
     * 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 obj, Object object) {
        if (object instanceof Proxy) {
            ProxyIndirectionHandler<?> handler = (ProxyIndirectionHandler<?>)Proxy.getInvocationHandler(object);
            ValueHolderInterface<?> valueHolder = handler.getValueHolder();
            return valueHolder.getValue();
        } else {
            return object;
        }
    }

    /**
     * INTERNAL:
     * Given a proxy object, trigger the indirection and return the actual object represented by the proxy.
     */
    public static Object getValueFromProxy(Object value) {
        if (Proxy.isProxyClass(value.getClass())) {
            return ((ProxyIndirectionHandler<?>)Proxy.getInvocationHandler(value)).getValueHolder().getValue();
        }
        return value;
    }

    /**
     * INTERNAL:
     * Set the "real" value of the attribute to attributeValue.
     */
    @Override
    public void setRealAttributeValueInObject(Object target, Object attributeValue) {
        this.getMapping().setAttributeValueInObject(target, attributeValue);
    }

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

    /**
     * INTERNAL:
     * An object has been serialized from the server to the client.  Replace the transient attributes of the
     * remote value holders with client-side objects.
     */
    @Override
    public void fixObjectReferences(Object object, Map<Object, ObjectDescriptor> objectDescriptors, Map<Object, Object> processedObjects, ObjectLevelReadQuery query, DistributedSession session) {
        //org.eclipse.persistence.internal.helper.Helper.toDo("*** Something tells me this isn't going to work. *** [X]");
    }

    /**
     * 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 ((referenceObject == null) || !Proxy.isProxyClass(referenceObject.getClass())) {
            return null;
        }

        ProxyIndirectionHandler<?> handler = (ProxyIndirectionHandler<?>)Proxy.getInvocationHandler(referenceObject);
        ValueHolderInterface<?> valueHolder = handler.getValueHolder();

        if (valueHolder.isInstantiated()) {
            return null;
        } else {
            return ((DatabaseValueHolder<?>)valueHolder).getRow();
        }
    }

    /**
     * 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
    @SuppressWarnings({"unchecked"})
    public Object cloneAttribute(Object attributeValue, Object original, CacheKey cacheKey, Object clone, Integer refreshCascade, AbstractSession cloningSession, boolean buildDirectlyFromRow) {
        if (!(attributeValue instanceof Proxy)) {
            boolean isExisting = !cloningSession.isUnitOfWork() || (((UnitOfWorkImpl)cloningSession).isObjectRegistered(clone) && (!((UnitOfWorkImpl)cloningSession).isOriginalNewObject(original)));
            return this.getMapping().buildCloneForPartObject(attributeValue, original, null, clone, cloningSession, refreshCascade, isExisting, !buildDirectlyFromRow);
        }

        ValueHolderInterface<Object> newValueHolder;
        ProxyIndirectionHandler<Object> handler = (ProxyIndirectionHandler<Object>)Proxy.getInvocationHandler(attributeValue);
        ValueHolderInterface<Object> oldValueHolder = handler.getValueHolder();

        if (!buildDirectlyFromRow && cloningSession.isUnitOfWork() && ((UnitOfWorkImpl)cloningSession).isOriginalNewObject(original)) {
            // CR#3156435 Throw a meaningful exception if a serialized/dead value holder is detected.
            // This can occur if an existing serialized object is attempt to be registered as new.
            if ((oldValueHolder instanceof DatabaseValueHolder)
                    && (! oldValueHolder.isInstantiated())
                    && (((DatabaseValueHolder<?>) oldValueHolder).getSession() == null)
                    && (! ((DatabaseValueHolder<?>) oldValueHolder).isSerializedRemoteUnitOfWorkValueHolder())) {
                throw DescriptorException.attemptToRegisterDeadIndirection(original, getMapping());
            }
            newValueHolder = new ValueHolder<>();
            newValueHolder.setValue(this.getMapping().buildCloneForPartObject(oldValueHolder.getValue(), original, null, clone, cloningSession, refreshCascade, false, false));
        } else {
            AbstractRecord row = null;
            if (oldValueHolder instanceof DatabaseValueHolder) {
                row = ((DatabaseValueHolder<?>)oldValueHolder).getRow();
            }
            newValueHolder = this.getMapping().createCloneValueHolder(oldValueHolder, original, clone, row, cloningSession, buildDirectlyFromRow);
        }

        return ProxyIndirectionHandler.newProxyInstance(attributeValue.getClass(), targetInterfaces, newValueHolder);
    }

    /**
     * INTERNAL:
     * Return a backup clone of the attribute.
     */
    @Override
    @SuppressWarnings({"unchecked"})
    public Object backupCloneAttribute(Object attributeValue, Object clone, Object backup, UnitOfWorkImpl unitOfWork) {
        if (!(attributeValue instanceof Proxy)) {
            return this.getMapping().buildBackupCloneForPartObject(attributeValue, clone, backup, unitOfWork);
        }
        ProxyIndirectionHandler<Object> handler = (ProxyIndirectionHandler<Object>)Proxy.getInvocationHandler(attributeValue);
        ValueHolderInterface<Object> unitOfWorkValueHolder = handler.getValueHolder();
        ValueHolderInterface<Object> backupValueHolder = null;

        if ((!(unitOfWorkValueHolder instanceof UnitOfWorkValueHolder)) || unitOfWorkValueHolder.isInstantiated()) {
            backupValueHolder = (ValueHolderInterface<Object>) super.backupCloneAttribute(unitOfWorkValueHolder, clone, backup, unitOfWork);
        } else {
            // CR#2852176 Use a BackupValueHolder to handle replacing of the original.
            backupValueHolder = new BackupValueHolder<>(unitOfWorkValueHolder);
            ((UnitOfWorkValueHolder<Object>)unitOfWorkValueHolder).setBackupValueHolder(backupValueHolder);
        }

        return ProxyIndirectionHandler.newProxyInstance(attributeValue.getClass(), targetInterfaces, backupValueHolder);
    }

    /**
     * INTERNAL:
     * Iterate over the specified attribute value.
     */
    @Override
    public void iterateOnAttributeValue(DescriptorIterator iterator, Object attributeValue) {
        if (attributeValue instanceof Proxy) {
            ProxyIndirectionHandler<?> handler = (ProxyIndirectionHandler<?>)Proxy.getInvocationHandler(attributeValue);
            ValueHolderInterface<?> valueHolder = handler.getValueHolder();

            iterator.iterateValueHolderForMapping(valueHolder, this.getMapping());
        } else {
            if (attributeValue != null) {
                this.getMapping().iterateOnRealAttributeValue(iterator, attributeValue);
            }
        }
    }

    /**
     * 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 non-null and implement some public interface.
     */
    @Override
    public Object validateAttributeOfInstantiatedObject(Object attributeValue) {
        if ((attributeValue != null) && (attributeValue.getClass().getInterfaces().length == 0) && attributeValue instanceof Proxy) {
            //org.eclipse.persistence.internal.helper.Helper.toDo("*** Need a new DescriptorException here. ***");
            //            throw DescriptorException.valueHolderInstantiationMismatch(attributeValue, this.getMapping());
            System.err.println("** ProxyIndirection attribute validation failed.");
        }
        return attributeValue;
    }

    /**
     * INTERNAL:
     * Verify that attribute type is correct for the indirection policy. If it is incorrect, add an exception to the
     * integrity checker.  In this case, the attribute type must be contained in targetInterfaces.
     */
    @Override
    public void validateDeclaredAttributeType(Class<?> attributeType, IntegrityChecker checker) throws DescriptorException {
        if (!isValidType(attributeType)) {
            checker.handleError(DescriptorException.invalidAttributeTypeForProxyIndirection(attributeType, targetInterfaces, getMapping()));
        }
    }

    /**
     * INTERNAL:
     * Verify that the return type of the attribute's get method is correct for the indirection policy. If it is
     * incorrect, add an exception to the integrity checker.  In this case, the return type must be a
     * public interface.
     */
    @Override
    public void validateGetMethodReturnType(Class<?> returnType, IntegrityChecker checker) throws DescriptorException {
        if (!isValidType(returnType)) {
            checker.handleError(DescriptorException.invalidGetMethodReturnTypeForProxyIndirection(returnType, targetInterfaces, getMapping()));
        }
    }

    /**
     * INTERNAL:
     * Verify that the parameter type of the attribute's set method is correct for the indirection policy. If it is
     * incorrect, add an exception to the integrity checker.  In this case, the parameter type must be a
     * public interface.
     */
    @Override
    public void validateSetMethodParameterType(Class<?> parameterType, IntegrityChecker checker) throws DescriptorException {
        if (!isValidType(parameterType)) {
            checker.handleError(DescriptorException.invalidSetMethodParameterTypeForProxyIndirection(parameterType, targetInterfaces, getMapping()));
        }
    }

    /**
     * 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:
     * Verify that a class type is valid to use for the proxy.  The class must be one of the
     * interfaces in <CODE>targetInterfaces</CODE>.
     */
    public boolean isValidType(Class<?> attributeType) {
        if (!attributeType.isInterface()) {
            return false;
        }
        for (int i = 0; i < targetInterfaces.length; i++) {
            if (attributeType == targetInterfaces[i]) {
                return true;
            }
        }
        return false;
    }
}
