/*
 * 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.beans.PropertyChangeListener;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedActionException;

import org.eclipse.persistence.descriptors.changetracking.ChangeTracker;
import org.eclipse.persistence.exceptions.DescriptorException;
import org.eclipse.persistence.indirection.ValueHolderInterface;
import org.eclipse.persistence.indirection.WeavedAttributeValueHolderInterface;
import org.eclipse.persistence.internal.helper.Helper;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.internal.security.PrivilegedMethodInvoker;
import org.eclipse.persistence.mappings.ForeignReferenceMapping;

/**
 * A WeavedObjectBasicIndirectionPolicy is used by OneToOne mappings that are LAZY through weaving
 * and which use Property(method) access.
 *
 * It extends BasicIndirection by providing the capability of calling the set method that was initially
 * mapped in addition to the set method for the weaved valueholder in order to coordinate the value of the
 * underlying property with the value stored in the valueholder
 *
 * @author Tom Ware
 */
public class WeavedObjectBasicIndirectionPolicy extends BasicIndirectionPolicy {
    /** Name of the initial set method. */
    protected String setMethodName = null;
    /** Lazily initialized set method based on the set method name. */
    protected transient Method setMethod = null;
    /** Name of the initial get method. */
    protected String getMethodName;
    /** indicates whether the mapping has originally used method access */
    protected boolean hasUsedMethodAccess;
    /** Stores the actual type of the mapping if different from the reference type.  Used for set method invocation*/
    protected String actualTypeClassName = null;

    public WeavedObjectBasicIndirectionPolicy(String getMethodName, String setMethodName, String actualTypeClassName, boolean hasUsedMethodAccess) {
        super();
        this.setMethodName = setMethodName;
        this.getMethodName = getMethodName;
        this.hasUsedMethodAccess = hasUsedMethodAccess;
        this.actualTypeClassName = actualTypeClassName;
    }


    public String getActualTypeClassName() {
        return actualTypeClassName;
    }

    /**
     * Return the "real" attribute value, as opposed to any wrapper.
     * This will trigger the wrapper to instantiate the value. In a weaved policy, this will
     * also call the initial setter method to coordinate the values of the valueholder with
     * the underlying data.
     */
    @Override
    public Object getRealAttributeValueFromObject(Object object, Object attribute) {
        boolean wasInstantiated = attribute != null && attribute instanceof ValueHolderInterface && ((ValueHolderInterface)attribute).isInstantiated();
        Object value = super.getRealAttributeValueFromObject(object, attribute);
        // Provide the indirection policy with a callback that allows it to do any updates it needs as the result of getting the value.
        if (!wasInstantiated && (value != attribute)) {
            //if the attribute was already unwrapped then do not call this method
            updateValueInObject(object, value, attribute);
        }
        return value;
    }

    /**
     * This method will lazily initialize the set method
     * Lazy initialization occurs to that we are not required to have a handle on
     * the actual class that we are using until runtime.  This helps to satisfy the
     * weaving requirement that demands that we avoid loading domain classes into
     * the main class loader until after weaving occurs.
     */
    protected Method getSetMethod() {
        if (setMethod == null) {
            ForeignReferenceMapping sourceMapping = (ForeignReferenceMapping)mapping;
            // The parameter type for the set method must always be the return type of the get method.
            Class<?>[] parameterTypes = new Class<?>[1];
            parameterTypes[0] = sourceMapping.getReferenceClass();

            try {
                setMethod = Helper.getDeclaredMethod(sourceMapping.getDescriptor().getJavaClass(), setMethodName, parameterTypes);
            } catch (NoSuchMethodException e) {
                if (actualTypeClassName != null) {
                    try {
                        // try the actual class of the field or property
                        parameterTypes[0] = Helper.getClassFromClasseName(actualTypeClassName, sourceMapping.getReferenceClass().getClassLoader());
                        setMethod = Helper.getDeclaredMethod(sourceMapping.getDescriptor().getJavaClass(), setMethodName, parameterTypes);
                    } catch (NoSuchMethodException nsme) {}
                    if (setMethod != null) {
                        return setMethod;
                    }
                }
                try {
                    // Get the set method type from the get method.
                    Method getMethod = Helper.getDeclaredMethod(sourceMapping.getDescriptor().getJavaClass(), getGetMethodName(), new Class<?>[0]);
                    parameterTypes[0] = getMethod.getReturnType();
                    setMethod = Helper.getDeclaredMethod(sourceMapping.getDescriptor().getJavaClass(), setMethodName, parameterTypes);
                } catch (NoSuchMethodException e2) {
                    // As a last ditch effort, change the parameter type to Object.class.
                    // If the model uses generics:
                    //   public T getStuntDouble()
                    //   public void setStuntDouble(T)
                    // The weaved methods will be:
                    //   public Object getStuntDouble() and
                    //   public void setStuntDouble(Object)
                    try {
                        parameterTypes[0] = Object.class;
                        setMethod = Helper.getDeclaredMethod(sourceMapping.getDescriptor().getJavaClass(), setMethodName, parameterTypes);
                    } catch (NoSuchMethodException e3) {
                        // Throw the original exception.
                        throw DescriptorException.errorAccessingSetMethodOfEntity(sourceMapping.getDescriptor().getJavaClass(), setMethodName, sourceMapping.getDescriptor(), e);
                    }
                }
            }
        }
        return setMethod;
    }


    /**
     * Coordinate the valueholder for this mapping with the underlying property by calling the
     * initial setter method.
     */
    public void updateValueInObject(Object object, Object value, Object attributeValue){
        setRealAttributeValueInObject(object, value);
        ((WeavedAttributeValueHolderInterface)attributeValue).setIsCoordinatedWithProperty(true);
    }

    /**
     * Set the value of the appropriate attribute of target to attributeValue.
     * In this case, place the value inside the target's ValueHolder.
     * Change tracking will be turned off when this method is called
     */
    @Override
    public void setRealAttributeValueInObject(Object target, Object attributeValue) {
        setRealAttributeValueInObject(target, attributeValue, false);
    }

    /**
     * Set the value of the appropriate attribute of target to attributeValue.
     * In this case, place the value inside the target's ValueHolder.
     * if trackChanges is true, set the value in the object as if the user was setting it.  Allow change tracking to pick up the change.
     */
    @Override
    public void setRealAttributeValueInObject(Object target, Object attributeValue, boolean trackChanges) {
        // If the target object is using change tracking, it must be disable first to avoid thinking the value changed.
        PropertyChangeListener listener = null;
        ChangeTracker trackedObject = null;
        if (!trackChanges && target instanceof ChangeTracker) {
            trackedObject = (ChangeTracker)target;
            listener = trackedObject._persistence_getPropertyChangeListener();
            trackedObject._persistence_setPropertyChangeListener(null);
        }
        Object[] parameters = new Object[1];
        parameters[0] = attributeValue;
        try {
            if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()) {
                try {
                    AccessController.doPrivileged(new PrivilegedMethodInvoker<>(getSetMethod(), target, parameters));
                } catch (PrivilegedActionException exception) {
                    Exception throwableException = exception.getException();
                    if (throwableException instanceof IllegalAccessException) {
                        throw DescriptorException.illegalAccessWhileSettingValueThruMethodAccessor(setMethod.getName(), attributeValue, throwableException);
                    } else {
                        throw DescriptorException.targetInvocationWhileSettingValueThruMethodAccessor(setMethod.getName(), attributeValue, throwableException);
                     }
                }
            } else {
                PrivilegedAccessHelper.invokeMethod(getSetMethod(), target, parameters);
            }
        } catch (IllegalAccessException exception) {
            throw DescriptorException.illegalAccessWhileSettingValueThruMethodAccessor(setMethod.getName(), attributeValue, exception);
        } catch (IllegalArgumentException exception) {
              throw DescriptorException.illegalArgumentWhileSettingValueThruMethodAccessor(setMethod.getName(), attributeValue, exception);
        } catch (InvocationTargetException exception) {
            throw DescriptorException.targetInvocationWhileSettingValueThruMethodAccessor(setMethod.getName(), attributeValue, exception);
        } finally {
            if (!trackChanges && trackedObject != null) {
                trackedObject._persistence_setPropertyChangeListener(listener);
            }
        }
    }

    public String getGetMethodName() {
        return this.getMethodName;
    }

    public String getSetMethodName() {
        return this.setMethodName;
    }

    public boolean hasUsedMethodAccess() {
        return this.hasUsedMethodAccess;
    }

    @Override
    public boolean isWeavedObjectBasicIndirectionPolicy() {
        return true;
    }
}
