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

import java.beans.PropertyChangeListener;

import java.util.*;

import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.internal.descriptors.changetracking.*;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.internal.sessions.ChangeRecord;
import org.eclipse.persistence.internal.sessions.ObjectChangeSet;
import org.eclipse.persistence.internal.sessions.UnitOfWorkChangeSet;
import org.eclipse.persistence.internal.sessions.UnitOfWorkImpl;
import org.eclipse.persistence.internal.descriptors.*;
import org.eclipse.persistence.mappings.*;
import org.eclipse.persistence.queries.FetchGroup;

/**
 * PUBLIC:
 * An AttributeChangeTrackingPolicy allows change tracking at the attribute level of an
 * object by implementing ChangeTracker.  Objects with changed attributes will
 * be processed in the UnitOfWork commit process to include any changes in the results of the
 * commit.  Unchanged objects will be ignored.
 * @see DeferredChangeDetectionPolicy
 * @see ObjectChangeTrackingPolicy
 * @see ChangeTracker
 */
public class AttributeChangeTrackingPolicy extends ObjectChangeTrackingPolicy {

    /**
     * INTERNAL:
     * PERF: Calculate change for the existing object, avoids check for new since already know.
     * Avoid backup clone, as not used.
     */
    @Override
    public ObjectChangeSet calculateChangesForExistingObject(Object clone, UnitOfWorkChangeSet changeSet, UnitOfWorkImpl unitOfWork, ClassDescriptor descriptor, boolean shouldRaiseEvent) {
        return calculateChanges(clone, null, false, changeSet, unitOfWork, descriptor, shouldRaiseEvent);
    }

    /**
     * INTERNAL:
     * Create ObjectChangeSet
     */
    @Override
    public ObjectChangeSet createObjectChangeSet(Object clone, Object backUp, org.eclipse.persistence.internal.sessions.UnitOfWorkChangeSet changeSet, boolean isNew, AbstractSession session, ClassDescriptor descriptor) {
        ObjectChangeSet changes = null;
        if (!isNew) {
            AttributeChangeListener listener = (AttributeChangeListener)((ChangeTracker)clone)._persistence_getPropertyChangeListener();
            if (listener != null){
                changes = listener.getObjectChangeSet();
            }

            // The changes can be null if forceUpdate is used in CMP, so an empty change must be created.
            if (changes != null) {
                // PERF: Only merge the change set if merging into a new uow change set.
                // merge the changeSet locally (ie the UOW's copy not the tracking policies copy) ; the local changeset will be returned.
                if (changes.getUOWChangeSet() != changeSet) {
                    changes = changeSet.mergeObjectChanges(changes, (org.eclipse.persistence.internal.sessions.UnitOfWorkChangeSet)changes.getUOWChangeSet());
                }
                // check for deferred changes
                if (changes.hasDeferredAttributes()){
                    //need to calculate the changes for these attributes.
                    for (Iterator<String> iterator = changes.getDeferredSet().iterator(); iterator.hasNext();){
                        DatabaseMapping mapping = descriptor.getObjectBuilder().getMappingForAttributeName(iterator.next());
                        mapping.calculateDeferredChanges((ChangeRecord)changes.getChangesForAttributeNamed(mapping.getAttributeName()), session);
                    }
                    changes.getDeferredSet().clear();
                }
            } else {
                changes = descriptor.getObjectBuilder().createObjectChangeSet(clone, changeSet, isNew, session);
            }
        } else {
            changes = descriptor.getObjectBuilder().createObjectChangeSet(clone, changeSet, isNew, true, session);
            // PERF: Do not create change records for new objects.
            if (descriptor.shouldUseFullChangeSetsForNewObjects() || descriptor.isAggregateDescriptor()) {
                FetchGroup fetchGroup = null;
                if(descriptor.hasFetchGroupManager()) {
                    fetchGroup = descriptor.getFetchGroupManager().getObjectFetchGroup(clone);
                }
                List<DatabaseMapping> mappings = descriptor.getMappings();
                int size = mappings.size();
                for (int index = 0; index < size; index++) {
                    DatabaseMapping mapping = mappings.get(index);
                    if ((fetchGroup == null) || fetchGroup.containsAttributeInternal(mapping.getAttributeName())) {
                        changes.addChange(mapping.compareForChange(clone, null, changes, session));
                    }
                }
            }
        }

        // The following code deals with reads that force changes to the flag associated with optimistic locking.
        if ((descriptor.usesOptimisticLocking()) && (changes.getId() != null)) {
            changes.setOptimisticLockingPolicyAndInitialWriteLockValue(descriptor.getOptimisticLockingPolicy(), session);
        }

        return changes;
    }

    /**
     * Used to track instances of the change policies without doing an instance of check
     */
    @Override
    public boolean isAttributeChangeTrackingPolicy(){
        return true;
    }

    /**
     * INTERNAL:
     * Clear the change set in the change event listener.
     */
    @Override
    public void updateWithChanges(Object object, ObjectChangeSet changeSet, UnitOfWorkImpl uow, ClassDescriptor descriptor) {
        clearChanges(object, uow, descriptor, false);
    }

    /**
     * INTERNAL:
     * In cases where a relationship with detached or new entities is merged into itself previous changes may have been recorded for
     * the detached/new entity that need to be updated.
     */
    @Override
    public void updateListenerForSelfMerge(ObjectChangeListener listener, ForeignReferenceMapping mapping, Object source, Object target, UnitOfWorkImpl unitOfWork){
        ChangeRecord record = (ChangeRecord) ((AttributeChangeListener)listener).getObjectChangeSet().getChangesForAttributeNamed(mapping.getAttributeName());
        mapping.updateChangeRecordForSelfMerge(record, source, target, (UnitOfWorkChangeSet) ((AttributeChangeListener)listener).getObjectChangeSet().getUOWChangeSet(), unitOfWork);
    }

    /**
     * INTERNAL:
     * Clear the change set in the change event listener.
     */
    @Override
    public void revertChanges(Object clone, ClassDescriptor descriptor, UnitOfWorkImpl uow, Map cloneMapping, boolean forRefresh) {
        clearChanges(clone, uow, descriptor, forRefresh);
        cloneMapping.put(clone, clone);
    }

    /**
     * INTERNAL:
     * Assign ChangeListener to an aggregate object
     */
    @Override
    public void setAggregateChangeListener(Object parent, Object aggregate, UnitOfWorkImpl uow, ClassDescriptor descriptor, String mappingAttribute){
        ((ChangeTracker)aggregate)._persistence_setPropertyChangeListener(new AggregateAttributeChangeListener(descriptor, uow, (AttributeChangeListener)((ChangeTracker)parent)._persistence_getPropertyChangeListener(), mappingAttribute, aggregate));

        // set change trackers for nested aggregates
        Iterator<DatabaseMapping> i = descriptor.getMappings().iterator();
        while (i.hasNext()){
            DatabaseMapping mapping = i.next();
            if (mapping.isAggregateObjectMapping()){
                AggregateObjectMapping aggregateMapping = (AggregateObjectMapping)mapping;
                Object nestedAggregate = aggregateMapping.getAttributeValueFromObject(aggregate);
                if (nestedAggregate != null && nestedAggregate instanceof ChangeTracker){
                    descriptor.getObjectChangePolicy().setAggregateChangeListener(aggregate, nestedAggregate, uow, aggregateMapping.getReferenceDescriptor(), aggregateMapping.getAttributeName());
                }
            }
        }
    }

    /**
     * INTERNAL:
     * Assign AttributeChangeListener to PropertyChangeListener
     */
    @Override
    public PropertyChangeListener setChangeListener(Object clone, UnitOfWorkImpl uow, ClassDescriptor descriptor) {
        AttributeChangeListener listener = new AttributeChangeListener(descriptor, uow, clone);
        ((ChangeTracker)clone)._persistence_setPropertyChangeListener(listener);
        return listener;
    }

     /**
     * INTERNAL:
     * Set the ObjectChangeSet on the Listener, initially used for aggregate support
     */
    @Override
    public void setChangeSetOnListener(ObjectChangeSet objectChangeSet, Object clone){
        ((AttributeChangeListener)((ChangeTracker)clone)._persistence_getPropertyChangeListener()).setObjectChangeSet(objectChangeSet);
    }

   /**
     * INTERNAL:
     * Only build backup clone
     */
    @Override
    public Object buildBackupClone(Object clone, ObjectBuilder builder, UnitOfWorkImpl uow) {
        return clone;
    }
}
