/*
 * 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:
// mmacivor - Feb 06/2009 - Initial implementation
package org.eclipse.persistence.internal.oxm.accessor;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

import org.eclipse.persistence.core.mappings.CoreAttributeAccessor;
import org.eclipse.persistence.descriptors.changetracking.ChangeTracker;
import org.eclipse.persistence.indirection.ValueHolder;
import org.eclipse.persistence.indirection.ValueHolderInterface;
import org.eclipse.persistence.indirection.WeavedAttributeValueHolderInterface;
import org.eclipse.persistence.mappings.AttributeAccessor;
/**
 * INTERNAL:
 * A custom AttriuteAccessor to be used when the same object is mapped in both
 * OXM and ORM. This will bridge the gap between the two for attributes that use
 * ValueHolders. Specifically for JPA weaving.
 * @author matt.macivor
 *
 */
public class OrmAttributeAccessor extends AttributeAccessor {
    private AttributeAccessor ormAccessor;
    private CoreAttributeAccessor oxmAccessor;
    private boolean isValueHolderProperty;
    private boolean isChangeTracking;

    public OrmAttributeAccessor(AttributeAccessor ormAccessor, CoreAttributeAccessor oxmAccessor) {
        this.ormAccessor = ormAccessor;
        this.oxmAccessor = oxmAccessor;
    }

    public void setValueHolderProperty(boolean isValueHolder) {
        isValueHolderProperty = isValueHolder;
    }

    public void setChangeTracking(boolean changeTracking) {
        this.isChangeTracking = changeTracking;
    }

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

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

    @Override
    public Object getAttributeValueFromObject(Object object) {
        if(isValueHolderProperty) {
            ValueHolderInterface<?> vh = (ValueHolderInterface<?>)ormAccessor.getAttributeValueFromObject(object);
            if(vh != null && !vh.isInstantiated()) {
                Object value = vh.getValue();
                oxmAccessor.setAttributeValueInObject(object, value);
                if(vh instanceof WeavedAttributeValueHolderInterface) {
                    ((WeavedAttributeValueHolderInterface<?>)vh).setIsCoordinatedWithProperty(true);
                }
            }
        }
        return oxmAccessor.getAttributeValueFromObject(object);
    }

    @Override
    public void setAttributeValueInObject(Object object, Object value) {
        if(isChangeTracking) {
            Object oldValue = getAttributeValueFromObject(object);
            PropertyChangeListener listener = ((ChangeTracker)object)._persistence_getPropertyChangeListener();
            if(listener != null) {
                listener.propertyChange(new PropertyChangeEvent(object, oxmAccessor.getAttributeName(), value, oldValue));
            }
        }
        if(isValueHolderProperty) {
            @SuppressWarnings({"unchecked"})
            ValueHolderInterface<Object> vh = (ValueHolderInterface<Object>)ormAccessor.getAttributeValueFromObject(object);
            if(vh == null) {
                vh = new ValueHolder<>();
                ((ValueHolder<?>)vh).setIsNewlyWeavedValueHolder(true);
            }
            vh.setValue(value);
            ormAccessor.setAttributeValueInObject(object, vh);
        }
        oxmAccessor.setAttributeValueInObject(object, value);
    }

    public AttributeAccessor getOrmAccessor() {
        return this.ormAccessor;
    }

    public CoreAttributeAccessor getOxmAccessor() {
        return this.oxmAccessor;
    }

    public void setOrmAccessor(AttributeAccessor accessor) {
        this.ormAccessor = accessor;
    }

    public void setOxmAccessor(AttributeAccessor accessor) {
        this.oxmAccessor = accessor;
    }

    @Override
    public Class<?> getAttributeClass() {
        return oxmAccessor.getAttributeClass();
    }

    @Override
    public boolean isMethodAttributeAccessor() {
        return oxmAccessor.isMethodAttributeAccessor();
    }

    @Override
    public String getAttributeName() {
        return oxmAccessor.getAttributeName();
    }
}
