/*
 * 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 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.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 {
            PrivilegedAccessHelper.callDoPrivilegedWithException(
                    () -> PrivilegedAccessHelper.invokeMethod(getSetMethod(), target, parameters),
                    (ex) -> {
                        if (ex instanceof IllegalAccessException) {
                            return DescriptorException.illegalAccessWhileSettingValueThruMethodAccessor(setMethod.getName(), attributeValue, ex);
                        } else if (ex instanceof IllegalArgumentException) {
                            return DescriptorException.illegalArgumentWhileSettingValueThruMethodAccessor(setMethod.getName(), attributeValue, ex);
                        } else if (ex instanceof InvocationTargetException) {
                            return DescriptorException.targetInvocationWhileSettingValueThruMethodAccessor(setMethod.getName(), attributeValue, ex);
                        }
                        // This indicates unexpected problem in the code
                        return new RuntimeException(String.format(
                                "Invocation of %s setter method failed", setMethod.getName()), ex);

                    }
            );
        } 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;
    }
}
