/*
 * 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 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 objectDescriptors, Map 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
    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 newValueHolder;
        ProxyIndirectionHandler handler = (ProxyIndirectionHandler)Proxy.getInvocationHandler(attributeValue);
        ValueHolderInterface 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
    public Object backupCloneAttribute(Object attributeValue, Object clone, Object backup, UnitOfWorkImpl unitOfWork) {
        if (!(attributeValue instanceof Proxy)) {
            return this.getMapping().buildBackupCloneForPartObject(attributeValue, clone, backup, unitOfWork);
        }
        ProxyIndirectionHandler handler = (ProxyIndirectionHandler)Proxy.getInvocationHandler(attributeValue);
        ValueHolderInterface<?> unitOfWorkValueHolder = handler.getValueHolder();
        ValueHolderInterface<?> backupValueHolder = null;

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