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

import java.util.ArrayList;
import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.descriptors.changetracking.CollectionChangeEvent;
import org.eclipse.persistence.exceptions.ValidationException;
import org.eclipse.persistence.internal.queries.ContainerPolicy;

/**
 * <p>
 * <b>Purpose</b>: This class holds the record of the changes made to a collection attribute of
 * an object.
 * <p>
 * <b>Description</b>: Collections must be compared to each other and added and removed objects must
 * be recorded separately.
 */
public class CollectionChangeRecord extends DeferrableChangeRecord implements org.eclipse.persistence.sessions.changesets.CollectionChangeRecord {

    /**
     * Contains the added values to the collection and their corresponding ChangeSets.
     */
    protected Map<ObjectChangeSet, ObjectChangeSet> addObjectList;

    /**
     * Contains the added values to the collection and their corresponding ChangeSets in order.
     */
    protected List<ObjectChangeSet> orderedAddObjects;

    /**
     * Contains the added values index to the collection.
     */
    protected Map<ObjectChangeSet, Integer> orderedAddObjectIndices;

    /**
     * Contains OrderedChangeObjects representing each change made to the collection.
     */
    protected List<OrderedChangeObject> orderedChangeObjectList;

    /**
     * Contains the removed values to the collection and their corresponding ChangeSets.
     */
    protected Map<Integer, ObjectChangeSet> orderedRemoveObjects;

    /**
     * Contains the removed values index to the collection.
     */
    protected transient List<Integer> orderedRemoveObjectIndices;

    /**
     * Contains a list of extra adds.  These extra adds are used by attribute change tracking
     * to replicate behavior when someone adds the same object to a list and removes it once.
     * In this case the object should still appear once in the change set.
     */
     protected transient List<ObjectChangeSet> addOverFlow;

    /**
     * Contains the removed values from the collection and their corresponding ChangeSets.
     */
    protected Map<ObjectChangeSet, ObjectChangeSet> removeObjectList;

    /**
     * Indicates whether IndirectList's order has been repaired.
     */
    protected boolean orderHasBeenRepaired;

    /**
     * This default constructor.
     */
    public CollectionChangeRecord() {
        super();
    }

    /**
     * Constructor for the ChangeRecord representing a collection mapping
     * @param owner the changeSet that uses this record
     */
    public CollectionChangeRecord(ObjectChangeSet owner) {
        this.owner = owner;
    }

    /**
     * This method takes a Map of objects, converts these into ObjectChangeSets.
     */
    public void addAdditionChange(Map objectChanges, ContainerPolicy cp, UnitOfWorkChangeSet changeSet, AbstractSession session) {
        Iterator enumtr = objectChanges.values().iterator();
        while (enumtr.hasNext()) {
            Object object = cp.unwrapElement(enumtr.next());
            ObjectChangeSet change = session.getDescriptor(object.getClass()).getObjectBuilder().createObjectChangeSet(object, changeSet, session);
            if (change.hasKeys()){
                // if change set has keys this is a map comparison.  Maps are
                // not supported in change tracking so do not need to prevent duplicates
                // when map support is added this will have to be refactored
                getAddObjectList().put(change, change);
            } else {
                if (getRemoveObjectList().containsKey(change)) {
                    getRemoveObjectList().remove(change);
                } else {
                    getAddObjectList().put(change, change);
                }
            }
        }
    }

    /**
     * This method takes a list of objects and converts them into
     * ObjectChangeSets. This method should only be called from a
     * ListContainerPolicy. Additions to the list are made by index, hence,
     * the second Map of objectChangesIndices.
     */
    public void addOrderedAdditionChange(List<Object> orderedObjectsToAdd, Map<Object, Integer> objectChangesIndices, UnitOfWorkChangeSet changeSet, AbstractSession session) {
        for (Object object : orderedObjectsToAdd) {
            ObjectChangeSet change = session.getDescriptor(object.getClass()).getObjectBuilder().createObjectChangeSet(object, changeSet, session);
            getOrderedAddObjects().add(change);
            getOrderedAddObjectIndices().put(change, objectChangesIndices.get(object));
        }
    }

    /**
     * This method takes a map of objects and converts them into
     * ObjectChangeSets. This method should only be called from a
     * ListContainerPolicy. Deletions from the list is made by index, hence,
     * the second Vector of indicesToRemove.
     */
    public void addOrderedRemoveChange(List<Integer> indicesToRemove, Map objectChanges, UnitOfWorkChangeSet changeSet, AbstractSession session) {
        this.orderedRemoveObjectIndices = indicesToRemove;

        for (Integer index : indicesToRemove) {
            Object object = objectChanges.get(index);
            ObjectChangeSet change = session.getDescriptor(object.getClass()).getObjectBuilder().createObjectChangeSet(object, changeSet, session);
            getOrderedRemoveObjects().put(index, change);
        }
    }

    /**
     * This method takes a Map of objects, converts these into ObjectChangeSets.
     */
    public void addRemoveChange(Map objectChanges, ContainerPolicy cp, UnitOfWorkChangeSet changeSet, AbstractSession session) {
        // There is no need to keep track of removed new objects because it will not be in the backup,
        // It will not be in the backup because it is new.
        if(objectChanges.isEmpty()) {
            return;
        }
        ClassDescriptor descriptor = this.mapping.getReferenceDescriptor();
        boolean hasChildren = (descriptor.hasInheritance() && descriptor.getInheritancePolicy().hasChildren())
                || descriptor.hasTablePerClassPolicy();
        Iterator enumtr = cp.getChangeValuesFrom(objectChanges);
        while (enumtr.hasNext()) {
            Object object = cp.unwrapElement(enumtr.next());
            if (hasChildren) {
                descriptor = getReferenceDescriptor(object, session);
            }
            ObjectChangeSet change = descriptor.getObjectBuilder().createObjectChangeSet(object, changeSet, session);
            if (change.hasKeys()) {
                // if change set has keys this is a map comparison.  Maps are
                // not support in change tracking so do not need to prevent duplicates
                // when map support is added this will have to be refactored
                getRemoveObjectList().put(change, change);
            } else {
                if (getAddObjectList().containsKey(change)) {
                    getAddObjectList().remove(change);
                } else {
                    getRemoveObjectList().put(change, change);
                }
            }
        }
    }

    /**
     * ADVANCED:
     * This method returns the collection of ChangeSets that were added to the collection.
     */
    @Override
    public Map<ObjectChangeSet, ObjectChangeSet> getAddObjectList() {
        if (addObjectList == null) {
            addObjectList = new IdentityHashMap(10);
        }
        return addObjectList;
    }

    /**
     * Returns a list of extra adds.
     * These extra adds are used by attribute change tracking
     * to replicate behavior when someone adds the same object to a list and removes it once.
     * In this case the object should still appear once in the change set.
     */
    public List<ObjectChangeSet> getAddOverFlow() {
        if (addOverFlow == null) {
            addOverFlow = new ArrayList();
        }
        return addOverFlow;
    }

    /**
     * Returns descriptor corresponding to the object.
     */
    ClassDescriptor getReferenceDescriptor(Object object, AbstractSession session) {
        return session.getClassDescriptor(object);
    }

    /**
     * PUBLIC:
     * This method returns the Map that contains the removed values from the collection
     * and their corresponding ChangeSets.
     */
    @Override
    public Map<ObjectChangeSet, ObjectChangeSet> getRemoveObjectList() {
        if (removeObjectList == null) {
            removeObjectList = new IdentityHashMap();
        }
        return removeObjectList;
    }

    /**
     * PUBLIC:
     * Returns true if the change set has changes.
     */
    @Override
    public boolean hasChanges() {
        return (!(  (this.addObjectList == null || this.addObjectList.isEmpty()) &&
                    (this.removeObjectList == null || this.removeObjectList.isEmpty()) &&
                    (this.orderedAddObjects == null || this.orderedAddObjects.isEmpty()) &&
                    (this.orderedRemoveObjects == null || this.orderedRemoveObjects.isEmpty()) &&
                    (this.orderedChangeObjectList == null || this.orderedChangeObjectList.isEmpty())))
                || getOwner().isNew();
    }

    /**
     * This method will be used to merge one record into another.
     */
    @Override
    public void mergeRecord(ChangeRecord mergeFromRecord, UnitOfWorkChangeSet mergeToChangeSet, UnitOfWorkChangeSet mergeFromChangeSet) {
        if (((DeferrableChangeRecord)mergeFromRecord).isDeferred()){
            if (this.hasChanges()){
                //merging into existing change record need to combine changes
                mergeFromRecord.getMapping().calculateDeferredChanges(mergeFromRecord, mergeToChangeSet.getSession());
            }else{
                if (! this.isDeferred){
                    this.originalCollection = ((DeferrableChangeRecord)mergeFromRecord).originalCollection;
                }
                this.isDeferred = true;
                this.latestCollection = ((DeferrableChangeRecord)mergeFromRecord).latestCollection;
                return;
            }
        }
        Map<ObjectChangeSet, ObjectChangeSet> changeSets = new HashMap<>();
        Iterator<ObjectChangeSet> addEnum = ((CollectionChangeRecord)mergeFromRecord).getAddObjectList().keySet().iterator();
        while (addEnum.hasNext()) {
            ObjectChangeSet mergingObject = addEnum.next();
            ObjectChangeSet localChangeSet = mergeToChangeSet.findOrIntegrateObjectChangeSet(mergingObject, mergeFromChangeSet);
            if (getRemoveObjectList().containsKey(localChangeSet)) {
                getRemoveObjectList().remove(localChangeSet);
            } else {
                changeSets.put(localChangeSet, localChangeSet);
            }
        }
        getAddObjectList().putAll(changeSets);
        changeSets = new HashMap<>();
        Iterator<ObjectChangeSet> removeEnum = ((CollectionChangeRecord)mergeFromRecord).getRemoveObjectList().keySet().iterator();
        while (removeEnum.hasNext()) {
            ObjectChangeSet mergingObject = removeEnum.next();
            ObjectChangeSet localChangeSet = mergeToChangeSet.findOrIntegrateObjectChangeSet(mergingObject, mergeFromChangeSet);
            if (getAddObjectList().containsKey(localChangeSet)) {
                getAddObjectList().remove(localChangeSet);
            } else {
                changeSets.put(localChangeSet, localChangeSet);
            }
        }
        getRemoveObjectList().putAll(changeSets);
        //237545: merge the changes for ordered list's attribute change tracking. (still need to check if deferred changes need to be merged)
        List<OrderedChangeObject> orderedChangeSets = new ArrayList<>();
        Iterator<OrderedChangeObject> orderedChangeObjectEnum = ((CollectionChangeRecord)mergeFromRecord).getOrderedChangeObjectList().iterator();
        while (orderedChangeObjectEnum.hasNext()) {
            OrderedChangeObject changeObject = orderedChangeObjectEnum.next();
            ObjectChangeSet mergingObject = changeObject.getChangeSet();
            ObjectChangeSet localChangeSet = mergeToChangeSet.findOrIntegrateObjectChangeSet(mergingObject, mergeFromChangeSet);

            OrderedChangeObject orderedChangeObject = new OrderedChangeObject(changeObject.getChangeType(), changeObject.getIndex(), localChangeSet);
            orderedChangeSets.add(orderedChangeObject);
        }
        getOrderedChangeObjectList().addAll(orderedChangeSets);
    }

    /**
     * Sets the Added objects list.
     */
    public void setAddObjectList(Map<ObjectChangeSet, ObjectChangeSet> objectChangesList) {
        this.addObjectList = objectChangesList;
    }

    /**
     * Sets the removed objects list.
     */
    public void setRemoveObjectList(Map<ObjectChangeSet, ObjectChangeSet> objectChangesList) {
        this.removeObjectList = objectChangesList;
    }

    /**
     * This method will be used to update the objectsChangeSets references.
     */
    @Override
    public void updateReferences(UnitOfWorkChangeSet mergeToChangeSet, UnitOfWorkChangeSet mergeFromChangeSet) {
        Map addList = new IdentityHashMap(this.getAddObjectList().size() + 1);
        Map removeList = new IdentityHashMap(this.getRemoveObjectList().size() + 1);
        // If we have ordered lists we need to iterate through those.
        if (getOrderedAddObjects().size() > 0 || getOrderedRemoveObjectIndices().size() > 0) {
            // Do the ordered adds first ...
            List<ObjectChangeSet> orderedAddList = new ArrayList(getOrderedAddObjects().size());
            Map orderedAddListIndices = new IdentityHashMap(getOrderedAddObjectIndices().size());

            for (int i = 0; i < getOrderedAddObjects().size(); i++) {
                ObjectChangeSet changeSet = getOrderedAddObjects().get(i);
                ObjectChangeSet localChangeSet = mergeToChangeSet.findOrIntegrateObjectChangeSet(changeSet, mergeFromChangeSet);

                orderedAddList.add(localChangeSet);
                orderedAddListIndices.put(localChangeSet, getOrderedAddObjectIndices().get(changeSet));

                // Object was actually added and not moved.
                if (getAddObjectList().containsKey(changeSet)) {
                    addList.put(localChangeSet, localChangeSet);
                }
            }

            setOrderedAddObjects(orderedAddList);
            setOrderedAddObjectIndices(orderedAddListIndices);

            // Do the ordered removes now ...
            Map orderedRemoveList = new HashMap(getOrderedRemoveObjects().size());
            for (Object index : getOrderedRemoveObjects().keySet()) {
                ObjectChangeSet changeSet = getOrderedRemoveObjects().get(index);
                ObjectChangeSet localChangeSet = mergeToChangeSet.findOrIntegrateObjectChangeSet(changeSet, mergeFromChangeSet);

                orderedRemoveList.put(index, localChangeSet);

                // Object was actually removed and not moved.
                if (getRemoveObjectList().containsKey(changeSet)) {
                    removeList.put(localChangeSet, localChangeSet);
                }
            }

            setOrderedRemoveObjects(orderedRemoveList);
            // Don't need to worry about the vector of indices (Integer's), just leave them as is.
        } else {
            Iterator<ObjectChangeSet> changes = getAddObjectList().values().iterator();
            while (changes.hasNext()) {
                ObjectChangeSet localChangeSet = mergeToChangeSet.findOrIntegrateObjectChangeSet(changes.next(), mergeFromChangeSet);
                addList.put(localChangeSet, localChangeSet);
            }

            changes = getRemoveObjectList().values().iterator();
            while (changes.hasNext()) {
                ObjectChangeSet localChangeSet = mergeToChangeSet.findOrIntegrateObjectChangeSet(changes.next(), mergeFromChangeSet);
                removeList.put(localChangeSet, localChangeSet);
            }
        }

        setAddObjectList(addList);
        setRemoveObjectList(removeList);
    }

    /**
     * This method returns the collection of ChangeSets in the order they were
     * added to the collection. This list includes those objects that were
     * moved within the collection.
     */
    public List<ObjectChangeSet> getOrderedAddObjects() {
        if (orderedAddObjects == null) {
            orderedAddObjects = new ArrayList();
        }

        return orderedAddObjects;
    }

    /**
     * This method returns the index of an object added to the collection.
     */
    public Integer getOrderedAddObjectIndex(ObjectChangeSet changes) {
        return getOrderedAddObjectIndices().get(changes);
    }

    /**
     * This method returns the collection of ChangeSets that they were
     * added to the collection.
     */
    public Map<ObjectChangeSet, Integer> getOrderedAddObjectIndices() {
        if (orderedAddObjectIndices == null) {
            orderedAddObjectIndices = new IdentityHashMap();
        }

        return orderedAddObjectIndices;
    }

    /**
     * This method returns the Vector of OrderedChangeObjects. These objects represent
     * all changes made to the collection, and their order in the vector represents the order
     * they were performed.
     */
    public List<OrderedChangeObject> getOrderedChangeObjectList() {
        if (orderedChangeObjectList == null) {
            orderedChangeObjectList = new ArrayList();
        }

        return orderedChangeObjectList;
    }

    /**
     * This method returns the ordered list of indices to remove from the collection.
     */
    public List<Integer> getOrderedRemoveObjectIndices() {
        if (this.orderedRemoveObjectIndices == null) {
            this.orderedRemoveObjectIndices = new ArrayList();
        }

        return this.orderedRemoveObjectIndices;
    }

    /**
     * This method returns the index of an object removed from the collection.
     */
    public Object getOrderedRemoveObject(Integer index) {
        return getOrderedRemoveObjects().get(index);
    }

    /**
     * This method returns the collection of ChangeSets of objects removed from
     * the collection.
     */
    public Map<Integer, ObjectChangeSet> getOrderedRemoveObjects() {
        if (this.orderedRemoveObjects == null) {
            this.orderedRemoveObjects = new HashMap();
        }

        return this.orderedRemoveObjects;
    }

    /**
     * Sets collection of ChangeSets (and their respective index) that they
     * were added to the collection.
     */
    public void setOrderedAddObjectIndices(Map<ObjectChangeSet, Integer> orderedAddObjectIndices) {
        this.orderedAddObjectIndices = orderedAddObjectIndices;
    }

    /**
     * Sets collection of ChangeSets that they were added to the collection.
     */
    public void setOrderedAddObjects(List<ObjectChangeSet> orderedAddObjects) {
        this.orderedAddObjects = orderedAddObjects;
    }

    public void setOrderedChangeObjectList(List<OrderedChangeObject> orderedChangeObjectList) {
        this.orderedChangeObjectList = orderedChangeObjectList;
    }

    /**
     * Sets collection of ChangeSets that they were removed from the collection.
     */
    public void setOrderedRemoveObjects(Map<Integer, ObjectChangeSet> orderedRemoveObjects) {
        this.orderedRemoveObjects = orderedRemoveObjects;
    }

    /**
     * The same size as original list,
     * at the i-th position holds the index of the i-th original object in the current list (-1 if the object was removed):
     * for example: {0, -1, 1, -1, 3} means that:
     *   previous(0) == current(0);
     *   previous(1) was removed;
     *   previous(2) == current(1);
     *   previous(3) was removed;
     *   previous(4) == current(3);
     */
    public List<Integer> getCurrentIndexesOfOriginalObjects(List newList) {
        int newSize = newList.size();
        List<Integer> currentIndexes = new ArrayList(newSize);
        for(int i=0; i < newSize; i++) {
            currentIndexes.add(i);
        }
        if(orderedChangeObjectList != null) {
            for (int i = this.orderedChangeObjectList.size() - 1; i>=0; i--) {
                OrderedChangeObject  orderedChange = orderedChangeObjectList.get(i);
                Object obj = orderedChange.getAddedOrRemovedObject();
                Integer index = orderedChange.getIndex();
                int changeType = orderedChange.getChangeType();
                if(changeType == CollectionChangeEvent.ADD) {
                    // the object was added - remove the corresponding index
                    if(index == null) {
                        currentIndexes.remove(currentIndexes.size()-1);
                    } else {
                        currentIndexes.remove(index.intValue());
                    }
                } else if(changeType == CollectionChangeEvent.REMOVE) {
                    // the object was removed - add its index in the new list
                    if(index == null) {
                        throw ValidationException.collectionRemoveEventWithNoIndex(getMapping());
                    } else {
                        currentIndexes.add(index, newList.indexOf(obj));
                    }
                }
            }
        }
        return currentIndexes;
    }

   /**
    * Recreates the original state of currentCollection.
    */
    @Override
   public void internalRecreateOriginalCollection(Object currentCollection, AbstractSession session) {
       ContainerPolicy cp = this.mapping.getContainerPolicy();
       if(orderedChangeObjectList == null || orderedChangeObjectList.isEmpty()) {
           if(this.removeObjectList != null) {
               Iterator<ObjectChangeSet> it = this.removeObjectList.keySet().iterator();
               while(it.hasNext()) {
                   ObjectChangeSet changeSet = it.next();
                   cp.addInto(changeSet.getUnitOfWorkClone(), currentCollection, session);
               }
           }
           if(this.addObjectList != null) {
               Iterator<ObjectChangeSet> it = this.addObjectList.keySet().iterator();
               while(it.hasNext()) {
                   ObjectChangeSet changeSet = it.next();
                   cp.removeFrom(changeSet.getUnitOfWorkClone(), currentCollection, session);
               }
           }
       } else {
           List originalList = (List)currentCollection;
           for (int i = this.orderedChangeObjectList.size() - 1; i>=0; i--) {
               OrderedChangeObject  orderedChange = this.orderedChangeObjectList.get(i);
               Object obj = orderedChange.getAddedOrRemovedObject();
               Integer index = orderedChange.getIndex();
               int changeType = orderedChange.getChangeType();
               if(changeType == CollectionChangeEvent.ADD) {
                   // the object was added - remove the corresponding index
                   if(index == null) {
                       originalList.remove(originalList.size()-1);
                   } else {
                       originalList.remove(index.intValue());
                   }
               } else if(changeType == CollectionChangeEvent.REMOVE) {
                   // the object was removed - add its index in the new list
                   if(index == null) {
                       throw ValidationException.collectionRemoveEventWithNoIndex(getMapping());
                   } else {
                       originalList.add(index, obj);
                   }
               }
           }
       }
   }

   public void setOrderHasBeenRepaired(boolean hasBeenRepaired) {
       this.orderHasBeenRepaired = hasBeenRepaired;
   }
   public boolean orderHasBeenRepaired() {
       return this.orderHasBeenRepaired;
   }

   /**
    * Clears info about added / removed objects set by change tracker.
    */
    @Override
   public void clearChanges() {
       if(orderedChangeObjectList != null) {
           this.orderedChangeObjectList.clear();
       }
       if(this.removeObjectList != null) {
           this.removeObjectList.clear();
       }
       if(this.addObjectList != null) {
           this.addObjectList.clear();
       }
   }
}
