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

import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.indirection.*;
import org.eclipse.persistence.internal.sessions.AbstractRecord;
import org.eclipse.persistence.internal.sessions.UnitOfWorkImpl;
import org.eclipse.persistence.mappings.*;

/**
 * UnitOfWorkQueryValueHolder wraps a database-stored object and
 * implements behavior to access it. The object is read from
 * the database by invoking a user-specified query.
 * This value holder is used only in the unit of work.
 *
 * @author    Sati
 */
public class UnitOfWorkQueryValueHolder<T> extends UnitOfWorkValueHolder<T> {
    protected UnitOfWorkQueryValueHolder() {
        super();
    }

    protected UnitOfWorkQueryValueHolder(ValueHolderInterface<T> attributeValue, Object clone, DatabaseMapping mapping, UnitOfWorkImpl unitOfWork) {
        super(attributeValue, clone, mapping, unitOfWork);
    }

    public UnitOfWorkQueryValueHolder(ValueHolderInterface<T> attributeValue, Object clone, ForeignReferenceMapping mapping, AbstractRecord row, UnitOfWorkImpl unitOfWork) {
        this(attributeValue, clone, mapping, unitOfWork);
        this.row = row;
    }

    /**
     * Backup the clone attribute value.
     */
    @Override
    protected Object buildBackupCloneFor(Object cloneAttributeValue) {
        return this.mapping.buildBackupCloneForPartObject(cloneAttributeValue, null, null, getUnitOfWork());
    }

    /**
     * Clone the original attribute value.
     */
    @Override
    @SuppressWarnings({"unchecked"})
    public T buildCloneFor(Object originalAttributeValue) {
        Integer refreshCascade = null;
        if (wrappedValueHolder instanceof QueryBasedValueHolder){
            refreshCascade = ((QueryBasedValueHolder<?>)getWrappedValueHolder()).getRefreshCascadePolicy();
        }
        T clone = (T) this.mapping.buildCloneForPartObject(originalAttributeValue, null, null, this.relationshipSourceObject, getUnitOfWork(), refreshCascade, true, true);
        // Bug 414801
        if (wrappedValueHolder.isInstantiated() && refreshCascade != null) {
            ((QueryBasedValueHolder<T>)getWrappedValueHolder()).setRefreshCascadePolicy(null);
        }
        return clone;
    }

    /**
     * Ensure that the backup value holder is populated.
     */
    @Override
    public void setValue(T theValue) {
        // Must force instantiation to be able to compare with the old value.
        if (!this.isInstantiated) {
            instantiate();
        }
        T oldValue = getValue();
        super.setValue(theValue);
        updateForeignReferenceSet(theValue, oldValue);
    }

    /**
     * INTERNAL:
     * Here we now must check for bi-directional relationship.
     * If the mapping has a relationship partner then we must maintain the original relationship.
     * We only worry about ObjectReferenceMappings as the collections mappings will be handled by transparentIndirection
     */
    public void updateForeignReferenceRemove(Object value) {
        DatabaseMapping sourceMapping = this.getMapping();
        if (sourceMapping == null) {
            //mapping is a transient attribute. If it does not exist then we have been serialized
            return;
        }

        if (sourceMapping.isPrivateOwned()) {
            // don't null out backpointer on private owned relationship because it will cause an
            // extra update.
            return;
        }

        //    ForeignReferenceMapping partner = (ForeignReferenceMapping)getMapping().getRelationshipPartner();
        ForeignReferenceMapping partner = this.getRelationshipPartnerFor(value);
        if (partner != null) {
            if (value != null) {
                Object unwrappedValue = partner.getDescriptor().getObjectBuilder().unwrapObject(value, getSession());
                Object oldParent = partner.getRealAttributeValueFromObject(unwrappedValue, getSession());
                Object sourceObject = getRelationshipSourceObject();

                if (oldParent == null) {
                    // value has already been set
                    return;
                }
                // PERF: If the collection is not instantiated, then do not instantiated it.
                if (partner.isCollectionMapping()) {
                    if ((!(oldParent instanceof IndirectContainer)) || ((IndirectContainer<?>)oldParent).isInstantiated()) {
                        if (!partner.getContainerPolicy().contains(sourceObject, oldParent, getSession())) {
                            // value has already been set
                            return;
                        }
                    }
                }

                if (partner.isObjectReferenceMapping()) {
                    // Check if it's already been set to null
                    partner.setRealAttributeValueInObject(unwrappedValue, null);
                } else if (partner.isCollectionMapping()) {
                    // If it is not in the collection then it has already been removed.
                    partner.getContainerPolicy().removeFrom(sourceObject, oldParent, getSession());
                }
            }
        }
    }

    /**
     * INTERNAL:
     * Here we now must check for bi-directional relationship.
     * If the mapping has a relationship partner then we must maintain the original relationship.
     * We only worry about ObjectReferenceMappings as the collections mappings will be handled by transparentIndirection
     */
    public void updateForeignReferenceSet(Object value, Object oldValue) {
        if (value instanceof Collection) {
            //I'm passing a collection into the valueholder not an object
            return;
        }
        if (getMapping() == null) {
            //mapping is a transient attribute. If it does not exist then we have been serialized
            return;
        }

        //    ForeignReferenceMapping partner = (ForeignReferenceMapping)getMapping().getRelationshipPartner();
        ForeignReferenceMapping partner = this.getRelationshipPartnerFor(value);
        if (partner != null) {
            if (value != null) {
                Object unwrappedValue = partner.getDescriptor().getObjectBuilder().unwrapObject(value, getSession());
                Object oldParent = partner.getRealAttributeValueFromObject(unwrappedValue, getSession());
                Object sourceObject = getRelationshipSourceObject();
                Object wrappedSource = getMapping().getDescriptor().getObjectBuilder().wrapObject(sourceObject, getSession());

                if (oldParent == sourceObject) {
                    // value has already been set
                    return;
                }
                // PERF: If the collection is not instantiated, then do not instantiated it.
                if (partner.isCollectionMapping()) {
                    if ((!(oldParent instanceof IndirectContainer)) || ((IndirectContainer<?>)oldParent).isInstantiated()) {
                        if (partner.getContainerPolicy().contains(sourceObject, oldParent, getSession())) {
                            // value has already been set
                            return;
                        }
                    }
                }

                // Set the Object that was referencing this value to reference null, or remove value from its collection
                if (oldParent != null) {
                    if (getMapping().isObjectReferenceMapping()) {
                        if (!partner.isCollectionMapping()) {
                            // If the back pointer is a collection it's OK that I'm adding myself into the collection
                            getMapping().setRealAttributeValueInObject(oldParent, null);
                        }
                    } else if (getMapping().isCollectionMapping() && (!partner.isManyToManyMapping())) {
                        getMapping().getContainerPolicy().removeFrom(unwrappedValue, getMapping().getRealAttributeValueFromObject(oldParent, getSession()), getSession());
                    }
                }

                if (oldValue != null) {
                    // CR 3487
                    Object unwrappedOldValue = partner.getDescriptor().getObjectBuilder().unwrapObject(oldValue, getSession());

                    // if this object was referencing a different object reset the back pointer on that object
                    if (partner.isObjectReferenceMapping()) {
                        partner.setRealAttributeValueInObject(unwrappedOldValue, null);
                    } else if (partner.isCollectionMapping()) {
                        partner.getContainerPolicy().removeFrom(sourceObject, partner.getRealAttributeValueFromObject(unwrappedOldValue, getSession()), getSession());
                    }
                }

                // Now set the back reference of the value being passed in to point to this object
                if (partner.isObjectReferenceMapping()) {
                    partner.setRealAttributeValueInObject(unwrappedValue, wrappedSource);
                } else if (partner.isCollectionMapping()) {
                    partner.getContainerPolicy().addInto(wrappedSource, oldParent, getSession());
                }
            } else {
                updateForeignReferenceRemove(oldValue);
            }
        }
    }

    /**
     * Helper method to retrieve the relationship partner mapping.  This will take inheritance
     * into account and return the mapping associated with correct subclass if necessary.  This
     * is needed for EJB 2.0 inheritance
     */
    private ForeignReferenceMapping getRelationshipPartnerFor(Object partnerObject) {
        ForeignReferenceMapping partner = (ForeignReferenceMapping)getMapping().getRelationshipPartner();
        if ((partner == null) || (partnerObject == null)) {
            // no partner, nothing to do
            return partner;
        }

        // if the target object is not an instance of the class type associated with the partner
        // mapping, try and look up the same partner mapping but as part of the partnerObject's
        // descriptor.  Only check if inheritance is involved...
        if (partner.getDescriptor().hasInheritance()) {
            ClassDescriptor partnerObjectDescriptor = this.getSession().getDescriptor(partnerObject);
            if (!(partner.getDescriptor().getJavaClass().isAssignableFrom(partnerObjectDescriptor.getJavaClass()))) {
                return (ForeignReferenceMapping)partnerObjectDescriptor.getObjectBuilder().getMappingForAttributeName(partner.getAttributeName());
            }
        }
        return partner;
    }
}
