/*
 * 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
//     01/29/2019-3.0 Sureshkumar Balakrishnan
//       - 541873: ENTITYMANAGER.DETACH() TRIGGERS LAZY LOADING INTO THE PERSISTENCE CONTEXT
package org.eclipse.persistence.internal.descriptors;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Stack;

import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.exceptions.DescriptorException;
import org.eclipse.persistence.indirection.IndirectCollection;
import org.eclipse.persistence.indirection.IndirectContainer;
import org.eclipse.persistence.indirection.ValueHolderInterface;
import org.eclipse.persistence.internal.queries.AttributeItem;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.queries.AttributeGroup;
import org.eclipse.persistence.queries.FetchGroup;

/**
 * This class provides a generic way of using the descriptor information
 * to traverse an object graph.
 * Define a subclass, or an inner class, that implements at least
 * #iterate(Object) to implement a new traversal
 * feature without having to change the mapping classes or the object builder.
 * It provides functionality such as a cascading depth, a stack of visited object,
 * and a collection of the visited objects.
 *
 * NOTE:
 * If this works nicely the merge manager, remote traversals, and maybe
 * even aspects of the commit manager could be converted to use this class.
 */
public abstract class DescriptorIterator {
    public static final int NoCascading = 1;
    public static final int CascadePrivateParts = 2;
    public static final int CascadeAllParts = 3;
    protected Map visitedObjects;
    protected Stack visitedStack;
    protected AbstractSession session;
    protected DatabaseMapping currentMapping;
    protected ClassDescriptor currentDescriptor;
    protected AttributeItem currentItem;
    protected AttributeGroup currentGroup;
    protected boolean usesGroup;
    /* Ignored if usesGroup is false.
     * If set to true allows visiting the same object several times -
     * as long as it hasn't been visited with the currentGroup.
     */
    protected boolean shouldTrackCurrentGroup;
    protected Object result;// this is a work area, typically used as a Collecting Parm
    protected boolean shouldIterateOverIndirectionObjects;
    protected boolean shouldIterateOverUninstantiatedIndirectionObjects;
    protected boolean shouldIterateOverWrappedObjects;
    protected boolean shouldIterateOnIndirectionObjects;
    protected boolean shouldIterateOnAggregates;
    protected boolean shouldIterateOnPrimitives;
    // false by default; true means if object has FetchGroup then don't iterate outside it.
    protected boolean shouldIterateOnFetchGroupAttributesOnly;
    protected boolean shouldBreak;
    protected int cascadeDepth;// see static constants below
    protected CascadeCondition cascadeCondition;
    protected boolean forDetach;

    /**
     * Construct a typical iterator:
     *    iterate over all the objects
     *    process the objects contained by "value holders"...
     *    ...but only if they have already been instantiated...
     *    ...and don't process the "value holders" themselves
     *    process "wrapped" objects
     *    skip aggregate objects
     *    skip primitives (Strings, Dates, Integers, etc.)
     */
    protected DescriptorIterator() {
        // 2612538 - the default size of Map (32) is appropriate
        this.visitedObjects = new IdentityHashMap();
        this.visitedStack = new Stack();
        this.cascadeDepth = CascadeAllParts;
        this.shouldIterateOverIndirectionObjects = true;// process the objects contained by ValueHolders...
        this.shouldIterateOverUninstantiatedIndirectionObjects = false;// ...but only if they have already been instantiated...
        this.shouldIterateOnIndirectionObjects = false;// ...and don't process the ValueHolders themselves
        this.shouldIterateOverWrappedObjects = true;// process "wrapped" objects
        this.shouldIterateOnAggregates = false;
        this.shouldIterateOnPrimitives = false;
        this.shouldIterateOnFetchGroupAttributesOnly = false;
        this.shouldBreak = false;
        this.cascadeCondition = new CascadeCondition();
    }

    public int getCascadeDepth() {
        return cascadeDepth;
    }

    public ClassDescriptor getCurrentDescriptor() {
        return currentDescriptor;
    }

    public DatabaseMapping getCurrentMapping() {
        return currentMapping;
    }

    public AttributeItem getCurrentItem() {
        return this.currentItem;
    }

    public AttributeGroup getCurrentGroup() {
        return this.currentGroup;
    }

    /**
     * Fetch and return the descriptor for the specified object.
     */
    protected ClassDescriptor getDescriptorFor(Object object) {
        ClassDescriptor result = getSession().getDescriptor(object);
        if (result == null) {
            throw DescriptorException.missingDescriptor(object.getClass().getName());
        }
        return result;
    }

    public Object getResult() {
        return result;
    }

    public AbstractSession getSession() {
        return session;
    }

    /**
     * Return the second-to-last object visited.
     */
    public Object getVisitedGrandparent() {
        Object parent = getVisitedStack().pop();
        Object result = getVisitedStack().peek();
        getVisitedStack().push(parent);
        return result;
    }

    public Map getVisitedObjects() {
        return visitedObjects;
    }

    /**
     * Return the last object visited.
     */
    public Object getVisitedParent() {
        return getVisitedStack().peek();
    }

    public Stack getVisitedStack() {
        return visitedStack;
    }

    /**
     * Iterate an aggregate object
     * (i.e. an object that is the target of an AggregateMapping).
     * Override this method if appropriate.
     */
    protected void internalIterateAggregateObject(Object aggregateObject) {
        iterate(aggregateObject);
    }

    /**
     * Iterate an indirect container (IndirectList or IndirectMap).
     * Override this method if appropriate.
     */
    protected void internalIterateIndirectContainer(IndirectContainer container) {
        iterate(container);
    }

    /**
     * Iterate a primitive object (String, Date, Integer, etc.).
     * Override this method if appropriate.
     */
    protected void internalIteratePrimitive(Object primitiveValue) {
        iterate(primitiveValue);
    }

    /**
     * Iterate a (a non-Aggregate) reference object.
     * Override this method if appropriate.
     */
    protected void internalIterateReferenceObject(Object referenceObject) {
        iterate(referenceObject);
    }

    /**
     * Iterate a value holder.
     * Override this method if appropriate.
     */
    protected void internalIterateValueHolder(ValueHolderInterface valueHolder) {
        iterate(valueHolder);
    }

    /**
     * To define a new iterator create a subclass and define at least this method.
     * Given an object or set of the objects, this method will be called on those
     * objects and any object connected to them by using the descriptors to
     * traverse the object graph.
     * Override the assorted #internalIterate*() methods if appropriate.
     */
    protected abstract void iterate(Object object);

    /**
     * Iterate on the mapping's reference object and
     * recursively iterate on the reference object's
     * reference objects.
     * This is used for aggregate and aggregate collection mappings, which are not iterated on by default.
     */
    public void iterateForAggregateMapping(Object aggregateObject, DatabaseMapping mapping, ClassDescriptor descriptor) {
        if (aggregateObject == null) {
            return;
        }
        setCurrentMapping(mapping);
        // aggregate descriptors are passed in because they could be part of an inheritance tree
        setCurrentDescriptor(descriptor);

        AttributeGroup currentGroupOriginal = null;
        AttributeItem currentItemOriginal = null;
        if(this.usesGroup) {
            currentGroupOriginal = this.currentGroup;
            currentItemOriginal = this.currentItem;
            this.currentGroup = this.currentItem.getGroup();
        }

        if (shouldIterateOnAggregates()) {// false by default
            internalIterateAggregateObject(aggregateObject);
            if (shouldBreak()) {
                setShouldBreak(false);
                if(this.usesGroup) {
                    this.currentGroup = currentGroupOriginal;
                    this.currentItem = currentItemOriginal;
                }
                return;
            }
        }

        iterateReferenceObjects(aggregateObject);
        if(this.usesGroup) {
            this.currentGroup = currentGroupOriginal;
            this.currentItem = currentItemOriginal;
        }
    }

    /**
     * Iterate on the indirection object for its mapping.
     */
    public void iterateIndirectContainerForMapping(IndirectContainer container, DatabaseMapping mapping) {
        setCurrentMapping(mapping);
        setCurrentDescriptor(null);

        if (shouldIterateOnIndirectionObjects()) {// false by default
            internalIterateIndirectContainer(container);
        }

        if (shouldIterateOverUninstantiatedIndirectionObjects() || (shouldIterateOverIndirectionObjects() && container.isInstantiated()) || isForDetach()) {
            // force instantiation only if specified
            mapping.iterateOnRealAttributeValue(this, container);
        } else if (shouldIterateOverIndirectionObjects()) {
            // PERF: Allow the indirect container to iterate any cached elements.
            if (container instanceof IndirectCollection)  {
                mapping.iterateOnRealAttributeValue(this, ((IndirectCollection)container).getAddedElements());
            }
        }
    }

    /**
     * Iterate on the primitive value for its mapping.
     */
    public void iteratePrimitiveForMapping(Object primitiveValue, DatabaseMapping mapping) {
        if (primitiveValue == null) {
            return;
        }
        setCurrentMapping(mapping);
        setCurrentDescriptor(null);

        if (shouldIterateOnPrimitives()) {// false by default
            AttributeGroup currentGroupOriginal = null;
            AttributeItem currentItemOriginal = null;
            if(this.usesGroup) {
                currentGroupOriginal = this.currentGroup;
                currentItemOriginal = this.currentItem;
                this.currentGroup = this.currentItem.getGroup();
            }

            internalIteratePrimitive(primitiveValue);

            if(this.usesGroup) {
                this.currentGroup = currentGroupOriginal;
                this.currentItem = currentItemOriginal;
            }
        }
    }

    /**
     * Iterate on the mapping's reference object and
     * recursively iterate on the reference object's
     * reference objects.
     */
    public void iterateReferenceObjectForMapping(Object referenceObject, DatabaseMapping mapping) {
        if (this.cascadeCondition.shouldNotCascade(mapping)) {
            return;
        }

        // When using wrapper policy in EJB the iteration can stop in certain cases,
        // this is because EJB forces beans to be registered anyway and clone identity can be violated
        // and the violated clones references to session objects should not be traversed.
        ClassDescriptor rd = mapping.getReferenceDescriptor();
        if ((!shouldIterateOverWrappedObjects()) && (rd != null) && (rd.hasWrapperPolicy())) {
            return;
        }
        if (referenceObject == null) {
            return;
        }

        if(this.usesGroup && this.shouldTrackCurrentGroup) {
            Set visited = (Set)getVisitedObjects().get(referenceObject);
            if(visited == null) {
                visited = new HashSet(1);
                visited.add(this.currentItem.getGroup());
                getVisitedObjects().put(referenceObject, visited);
            } else {
                if(visited.contains(this.currentItem.getGroup())) {
                    // source object has been already visited with an equal group
                    return;
                } else {
                    visited.add(this.currentItem.getGroup());
                }
            }
        } else {
            // Check if already processed.
            if (getVisitedObjects().containsKey(referenceObject)) {
                return;
            }

            getVisitedObjects().put(referenceObject, referenceObject);
        }
        setCurrentMapping(mapping);
        setCurrentDescriptor(getDescriptorFor(referenceObject));

        AttributeGroup currentGroupOriginal = null;
        AttributeItem currentItemOriginal = null;
        if(this.usesGroup) {
            currentGroupOriginal = this.currentGroup;
            currentItemOriginal = this.currentItem;
            this.currentGroup = this.currentItem.getGroup();
        }

        internalIterateReferenceObject(referenceObject);
        if (shouldBreak()) {
            setShouldBreak(false);
            if(this.usesGroup) {
                this.currentGroup = currentGroupOriginal;
                this.currentItem = currentItemOriginal;
            }
            return;
        }

        iterateReferenceObjects(referenceObject);
        if(this.usesGroup) {
            this.currentGroup = currentGroupOriginal;
            this.currentItem = currentItemOriginal;
        }
    }

    /**
     * Iterate over the sourceObject's reference objects,
     * updating the visited stack appropriately.
     */
    protected void iterateReferenceObjects(Object sourceObject) {
        if(this.usesGroup) {
            // object is outside of the group - don't iterate over its references
            if(this.currentGroup == null || !this.currentGroup.hasItems()) {
                return;
            }
        }

        getVisitedStack().push(sourceObject);
        internalIterateReferenceObjects(sourceObject);
        getVisitedStack().pop();
    }

    protected void internalIterateReferenceObjects(Object sourceObject) {
        List<DatabaseMapping> mappings;
        // Only iterate on relationships if required.
        if (shouldIterateOnPrimitives()) {
            mappings = getCurrentDescriptor().getObjectBuilder().getDescriptor().getMappings();
        } else {
            ObjectBuilder builder = getCurrentDescriptor().getObjectBuilder().getDescriptor().getObjectBuilder();
            // PERF: Only process relationships.
            if (builder.isSimple()) {
                return;
            }
            mappings = builder.getRelationshipMappings();
        }

        if (shouldIterateOnFetchGroupAttributesOnly()) {
            if(getCurrentDescriptor().hasFetchGroupManager()) {
                FetchGroup fetchGroup = getCurrentDescriptor().getFetchGroupManager().getObjectFetchGroup(sourceObject);
                if (fetchGroup != null) {
                    List<DatabaseMapping> fetchGroupMappings = new ArrayList();
                    for (DatabaseMapping mapping : mappings) {
                        if (fetchGroup.containsAttributeInternal(mapping.getAttributeName())) {
                            fetchGroupMappings.add(mapping);
                        }
                    }
                    mappings = fetchGroupMappings;
                }
            }
        }

        if (this.usesGroup) {
            AttributeGroup currentGroupOriginal = this.currentGroup;
            AttributeItem currentItemOriginal = this.currentItem;
            for (DatabaseMapping mapping : mappings) {
                this.currentItem = this.currentGroup.getAllItems().get(mapping.getAttributeName());
                // iterate only over the mappings found in the group
                if (currentItem != null) {
                    mapping.iterate(this);
                    this.currentGroup = currentGroupOriginal;
                }
            }
            this.currentItem = currentItemOriginal;
        } else {
            for (DatabaseMapping mapping : mappings) {
                mapping.iterate(this);
            }
        }
    }

    /**
     * Iterate on the value holder for its mapping.
     */
    public void iterateValueHolderForMapping(ValueHolderInterface valueHolder, DatabaseMapping mapping) {
        setCurrentMapping(mapping);
        setCurrentDescriptor(null);

        if (shouldIterateOnIndirectionObjects()) {// false by default
            internalIterateValueHolder(valueHolder);
        }

        if (shouldIterateOverUninstantiatedIndirectionObjects() || (shouldIterateOverIndirectionObjects() && valueHolder.isInstantiated())) {
            // force instantiation only if specified
            mapping.iterateOnRealAttributeValue(this, valueHolder.getValue());
        }
    }

    public void setCascadeDepth(int cascadeDepth) {
        this.cascadeDepth = cascadeDepth;
    }

    public void setCascadeCondition(CascadeCondition cascadeCondition){
        this.cascadeCondition = cascadeCondition;
    }

    public void setCurrentDescriptor(ClassDescriptor currentDescriptor) {
        this.currentDescriptor = currentDescriptor;
    }

    public void setCurrentMapping(DatabaseMapping currentMapping) {
        this.currentMapping = currentMapping;
    }

    public void setCurrentItem(AttributeItem item) {
        this.currentItem = item;
    }

    public void setCurrentGroup(AttributeGroup group) {
        this.currentGroup = group;
    }

    public void setResult(Object result) {
        this.result = result;
    }

    public void setSession(AbstractSession session) {
        this.session = session;
    }

    public void setShouldBreak(boolean shouldBreak) {
        this.shouldBreak = shouldBreak;
    }

    /**
     * Set whether the aggregate reference objects themselves
     * should be processed. (The objects referenced by the aggregate
     * objects will be processed either way.)
     */
    public void setShouldIterateOnAggregates(boolean shouldIterateOnAggregates) {
        this.shouldIterateOnAggregates = shouldIterateOnAggregates;
    }

    /**
     * Set whether the attributes outside fetch group should be processed.
     */
    public void setShouldIterateOnFetchGroupAttributesOnly(boolean shouldIterateOnFetchGroupAttributesOnly) {
        this.shouldIterateOnFetchGroupAttributesOnly = shouldIterateOnFetchGroupAttributesOnly;
    }

    /**
     * Set whether the indirection objects themselves (e.g. the ValueHolders)
     * should be processed.
     */
    public void setShouldIterateOnIndirectionObjects(boolean shouldIterateOnIndirectionObjects) {
        this.shouldIterateOnIndirectionObjects = shouldIterateOnIndirectionObjects;
    }

    /**
     * Set whether to process primitive reference objects
     * (e.g. Strings, Dates, ints).
     */
    public void setShouldIterateOnPrimitives(boolean shouldIterateOnPrimitives) {
        this.shouldIterateOnPrimitives = shouldIterateOnPrimitives;
    }

    /**
     * Set whether to process the objects contained by indirection objects
     * (e.g. a ValueHolder's value) - but *without* instantiating them.
     * @see #setShouldIterateOverUninstantiatedIndirectionObjects(boolean)
     */
    public void setShouldIterateOverIndirectionObjects(boolean shouldIterateOverIndirectionObjects) {
        this.shouldIterateOverIndirectionObjects = shouldIterateOverIndirectionObjects;
    }

    /**
     * Set whether to *instantiate* and process the objects
     * contained by indirection objects (e.g. a ValueHolder's value).
     */
    public void setShouldIterateOverUninstantiatedIndirectionObjects(boolean shouldIterateOverUninstantiatedIndirectionObjects) {
        this.shouldIterateOverUninstantiatedIndirectionObjects = shouldIterateOverUninstantiatedIndirectionObjects;
    }

    public void setShouldIterateOverWrappedObjects(boolean shouldIterateOverWrappedObjects) {
        this.shouldIterateOverWrappedObjects = shouldIterateOverWrappedObjects;
    }

    public void setShouldTrackCurrentGroup(boolean shouldTrackCurrentGroup) {
        this.shouldTrackCurrentGroup = shouldTrackCurrentGroup;
    }

    public void setVisitedObjects(Map visitedObjects) {
        this.visitedObjects = visitedObjects;
    }

    protected void setVisitedStack(Stack visitedStack) {
        this.visitedStack = visitedStack;
    }

    public boolean shouldBreak() {
        return shouldBreak;
    }

    public boolean shouldCascadeAllParts() {
        return getCascadeDepth() == CascadeAllParts;
    }

    public boolean shouldCascadeNoParts() {
        return (getCascadeDepth() == NoCascading);
    }

    public boolean shouldCascadePrivateParts() {
        return (getCascadeDepth() == CascadeAllParts) || (getCascadeDepth() == CascadePrivateParts);
    }

    /**
     * Return whether the aggregate reference objects themselves
     * should be processed. (The objects referenced by the aggregate
     * objects will be processed either way.)
     */
    public boolean shouldIterateOnAggregates() {
        return shouldIterateOnAggregates;
    }

    /**
     * If true then if object has a FetchGroup then iterations
     * not performed on mappings that are outside of the FetchGroup.
     */
    public boolean shouldIterateOnFetchGroupAttributesOnly() {
        return this.shouldIterateOnFetchGroupAttributesOnly;
    }

    /**
     * Return whether the indirection objects themselves (e.g. the ValueHolders)
     * should be processed.
     */
    public boolean shouldIterateOnIndirectionObjects() {
        return shouldIterateOnIndirectionObjects;
    }

    /**
     * Return whether to process primitive reference objects
     * (e.g. Strings, Dates, ints).
     */
    public boolean shouldIterateOnPrimitives() {
        return shouldIterateOnPrimitives;
    }

    /**
     * Return whether to process the objects contained by indirection objects
     * (e.g. a ValueHolder's value) - but *without* instantiating them.
     * @see #shouldIterateOverUninstantiatedIndirectionObjects()
     */
    public boolean shouldIterateOverIndirectionObjects() {
        return shouldIterateOverIndirectionObjects;
    }

    /**
     * Return whether to *instantiate* and process the objects
     * contained by indirection objects (e.g. a ValueHolder's value).
     */
    public boolean shouldIterateOverUninstantiatedIndirectionObjects() {
        return shouldIterateOverUninstantiatedIndirectionObjects;
    }

    public boolean shouldIterateOverWrappedObjects() {
        return shouldIterateOverWrappedObjects;
    }

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

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

    /**
     * This is the root method called to start the iteration.
     */
    public void startIterationOn(Object sourceObject) {
        startIterationOn(sourceObject, null);
    }

    public void startIterationOn(Object sourceObject, AttributeGroup group) {
        this.usesGroup = group != null;
        if(this.usesGroup && this.shouldTrackCurrentGroup) {
            Set visited = (Set)getVisitedObjects().get(sourceObject);
            if(visited == null) {
                visited = new HashSet(1);
                visited.add(group);
                getVisitedObjects().put(sourceObject, visited);
            } else {
                if(visited.contains(group)) {
                    // source object has been already visited with an equal group
                    return;
                } else {
                    visited.add(group);
                }
            }
        } else {
            if (getVisitedObjects().containsKey(sourceObject)) {
                return;
            }
            getVisitedObjects().put(sourceObject, sourceObject);
        }
        setCurrentMapping(null);
        setCurrentDescriptor(getSession().getDescriptor(sourceObject));
        setCurrentItem(null);
        setCurrentGroup(group);

        iterate(sourceObject);

        // start the recursion
        if ((getCurrentDescriptor() != null) && (!shouldCascadeNoParts())  && !this.shouldBreak()) {
            iterateReferenceObjects(sourceObject);
        }
    }

    public class CascadeCondition{
        /**
         * Default constructor.
         */
        public CascadeCondition() {
        }

        public boolean shouldNotCascade(DatabaseMapping mapping){
            return !(shouldCascadeAllParts() || (shouldCascadePrivateParts() && mapping.isPrivateOwned()));
        }
    }

    public boolean isForDetach() {
        return forDetach;
    }

    public void setForDetach(boolean forDetach) {
        this.forDetach = forDetach;
    }
}
