/*
 * 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.descriptors;

import java.lang.reflect.Field;

import org.eclipse.persistence.exceptions.DescriptorException;
import org.eclipse.persistence.internal.helper.ConversionManager;
import org.eclipse.persistence.internal.helper.Helper;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.mappings.AttributeAccessor;

/**
 * <p><b>Purpose</b>: A wrapper class for handling cases when the domain object has instance variable
 * to map to the database field.
 *
 * @author Sati
 * @since TOPLink/Java 1.0
 */
public class InstanceVariableAttributeAccessor extends AttributeAccessor {

    /** The attribute name of an object is converted to Field type to access it reflectively */
    protected transient Field attributeField;

    /**
     * Returns the class type of the attribute.
     */
    @Override
    public Class<?> getAttributeClass() {
        if (getAttributeField() == null) {
            return null;
        }

        return getAttributeType();
    }

    /**
     * Returns the value of attributeField.
     * 266912: For Metamodel API - change visibility from protected
     */
    public Field getAttributeField() {
        return attributeField;
    }

    /**
     * Returns the declared type of attributeField.
     */
    public Class<?> getAttributeType() {
        return attributeField.getType();
    }

    /**
     * Returns the value of the attribute on the specified object.
     */
    @Override
    public Object getAttributeValueFromObject(Object anObject) throws DescriptorException {
        return PrivilegedAccessHelper.callDoPrivilegedWithException(
                () -> attributeField.get(anObject),
                (ex) -> {
                    if (ex instanceof IllegalArgumentException) {
                        return DescriptorException.illegalArgumentWhileGettingValueThruInstanceVariableAccessor(
                                getAttributeName(), getAttributeType().getName(), anObject.getClass().getName(), ex);
                    } else if (ex instanceof IllegalAccessException) {
                        return DescriptorException.illegalAccesstWhileGettingValueThruInstanceVaraibleAccessor(getAttributeName(), anObject.getClass().getName(), ex);
                    } else if (ex instanceof NullPointerException) {
                        final String className = anObject != null ? anObject.getClass().getName() : null;
                        return DescriptorException.nullPointerWhileGettingValueThruInstanceVariableAccessor(getAttributeName(), className, ex);
                    }
                    // This indicates unexpected problem in the code
                    throw new RuntimeException(String.format("Getting value from %s field failed", this.attributeField.getName()), ex);
                }
        );
    }

    /**
     * instanceVariableName is converted to Field type.
     */
    @Override
    public void initializeAttributes(Class<?> theJavaClass) throws DescriptorException {
        if (getAttributeName() == null) {
            throw DescriptorException.attributeNameNotSpecified();
        }
        try {
            setAttributeField(Helper.getField(theJavaClass, getAttributeName()));
        } catch (NoSuchFieldException exception) {
            throw DescriptorException.noSuchFieldWhileInitializingAttributesInInstanceVariableAccessor(getAttributeName(), theJavaClass.getName(), exception);
        } catch (SecurityException exception) {
            throw DescriptorException.securityWhileInitializingAttributesInInstanceVariableAccessor(getAttributeName(), theJavaClass.getName(), exception);
        }
    }

    /**
     * Returns true if this attribute accessor has been initialized and now stores a reference to the
     * class's attribute.  An attribute accessor can become uninitialized on serialization.
     */
    @Override
    public boolean isInitialized(){
        return this.attributeField !=  null;
    }

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

    /**
     * Sets the value of the attributeField.
     */
    protected void setAttributeField(Field field) {
        attributeField = field;
    }

    /**
     * Sets the value of the instance variable in the object to the value.
     */
    @Override
    public void setAttributeValueInObject(final Object anObject, final Object value) throws DescriptorException {
        try {
            // PERF: Direct variable access.
            PrivilegedAccessHelper.callDoPrivilegedWithException(
                    () -> this.attributeField.set(anObject, value)
            );
        } catch (IllegalArgumentException exception) {
            // This is done to overcome VA Java bug because VA Java does not allow null to be set reflectively.
            // This is done to overcome VA Java bug because VA Java does not allow null to be set reflectively.
            // Bug2910086 In JDK1.4, IllegalArgumentException is thrown if value is null.
            // TODO: This code should be removed, it should not be required and may cause unwanted side-effects.
            if (value == null) {
                // cr 3737  If a null pointer was thrown because we attempted to set a null reference into a
                // primitive create a primitive of value 0 to set in the object.
                final Class<?> fieldClass = getAttributeClass();
                if (org.eclipse.persistence.internal.helper.Helper.isPrimitiveWrapper(fieldClass)) {
                    PrivilegedAccessHelper.callDoPrivilegedWithException(
                            () -> PrivilegedAccessHelper.setValueInField(this.attributeField, anObject, ConversionManager.getDefaultManager().convertObject(0, fieldClass)),
                            (ex) -> DescriptorException.nullPointerWhileSettingValueThruInstanceVariableAccessor(getAttributeName(), null, ex)
                    );
                }
                return;
            }
            // TODO: This code should be removed, it should not be required and may cause unwanted side-effects.
            // Allow XML change set to merge correctly since new value in XML change set is always String
            try {
                if (value instanceof String) {
                    final Object newValue = ConversionManager.getDefaultManager().convertObject(value, getAttributeClass());
                    PrivilegedAccessHelper.callDoPrivilegedWithException(
                            () -> PrivilegedAccessHelper.setValueInField(this.attributeField, anObject, newValue)
                    );
                    return;
                }
            } catch (Exception e) {
                // Do nothing and move on to throw the original exception
            }
            throw DescriptorException.illegalArgumentWhileSettingValueThruInstanceVariableAccessor(getAttributeName(), getAttributeType().getName(), value, exception);
        } catch (IllegalAccessException exception) {
            if (value == null) {
                return;
            }
            throw DescriptorException.illegalAccessWhileSettingValueThruInstanceVariableAccessor(getAttributeName(), anObject.getClass().getName(), value, exception);
        } catch (NullPointerException exception) {
            // TODO: This code should be removed, it should not be required and may cause unwanted side-effects.
            //Bug2910086 In JDK1.3, NullPointerException is thrown if value is null.  Add a null pointer check so that the TopLink exception is thrown if anObject is null.
            if (anObject != null) {
                // cr 3737  If a null pointer was thrown because we attempted to set a null reference into a
                // primitive create a primitive of value 0 to set in the object.
                final Class<?> fieldClass = getAttributeClass();
                if (org.eclipse.persistence.internal.helper.Helper.isPrimitiveWrapper(fieldClass) && (value == null)) {
                    if (org.eclipse.persistence.internal.helper.Helper.isPrimitiveWrapper(fieldClass)) {
                        PrivilegedAccessHelper.callDoPrivilegedWithException(
                                () -> PrivilegedAccessHelper.setValueInField(this.attributeField, anObject, ConversionManager.getDefaultManager().convertObject(0, fieldClass)),
                                (ex) -> DescriptorException.nullPointerWhileSettingValueThruInstanceVariableAccessor(getAttributeName(), null, ex)
                        );
                    }
                } else {
                    throw DescriptorException.nullPointerWhileSettingValueThruInstanceVariableAccessor(getAttributeName(), value, exception);
                }
            } else {
                // Some JVM's throw this exception for some very odd reason
                throw DescriptorException.nullPointerWhileSettingValueThruInstanceVariableAccessor(getAttributeName(), value, exception);
            }
        // This indicates unexpected problem in the code
        } catch (Exception ex) {
            throw new RuntimeException(String.format("Setting value in %s field failed", this.attributeField.getName()), ex);
        }
    }
}
