/*
 * 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.*;
import org.eclipse.persistence.descriptors.InheritancePolicy;
import org.eclipse.persistence.mappings.*;
import org.eclipse.persistence.internal.helper.*;
import org.eclipse.persistence.internal.localization.*;
import org.eclipse.persistence.descriptors.ClassDescriptor;

/**
 * This wraps a descriptor with information required to compute an order for
 * dependencies. The algorithm is a simple topological sort.
 */
public class CommitOrderDependencyNode {
    protected CommitOrderCalculator owner;
    protected ClassDescriptor descriptor;
    protected AbstractSession session;

    // These are the descriptors to which we have 1:1 relationships
    protected Vector relatedNodes;
    protected CommitOrderDependencyNode predecessor;

    // Indicates the state of the traversal
    protected int traversalState;
    static public int NotVisited = 1;
    static public int InProgress = 2;
    static public int Visited = 3;

    // When we first saw this node in the traversal
    protected int discoveryTime;

    // When we finished visiting this node
    protected int finishingTime;

    public CommitOrderDependencyNode(CommitOrderCalculator calculator, ClassDescriptor descriptor, AbstractSession session) {
        this.owner = calculator;
        this.descriptor = descriptor;
        this.relatedNodes = new Vector();
        this.session = session;
    }

    public ClassDescriptor getDescriptor() {
        return descriptor;
    }

    public int getFinishingTime() {
        return finishingTime;
    }

    public CommitOrderCalculator getOwner() {
        return owner;
    }

    public CommitOrderDependencyNode getPredecessor() {
        return predecessor;
    }

    public Vector getRelatedNodes() {
        return relatedNodes;
    }

    public boolean hasBeenVisited() {
        return (traversalState == Visited);
    }

    public boolean hasNotBeenVisited() {
        return (traversalState == NotVisited);
    }

    public void markInProgress() {
        traversalState = InProgress;
    }

    public void markNotVisited() {
        traversalState = NotVisited;
    }

    public void markVisited() {
        traversalState = Visited;
    }

    /**
     * Add all owned classes for each descriptor through checking the mappings.
     * If I have a foreign mapping with a constraint dependency, then add it
     * If I'm related to a class, I'm related to all its subclasses and superclasses.
     * If my superclass is related to a class, I'm related to it.
     */
    public void recordMappingDependencies() {
        for (Enumeration<DatabaseMapping> mappings = getDescriptor().getMappings().elements();
             mappings.hasMoreElements();) {
            DatabaseMapping mapping = (DatabaseMapping)mappings.nextElement();
            if (mapping.isForeignReferenceMapping()) {
                if (mapping.hasConstraintDependency()) {
                    Class ownedClass;
                    ClassDescriptor refDescriptor = mapping.getReferenceDescriptor();
                    if (refDescriptor == null) {
                        refDescriptor = session.getDescriptor(((ForeignReferenceMapping)mapping).getReferenceClass());
                    }
                    ownedClass = refDescriptor.getJavaClass();

                    if (ownedClass == null) {
                        throw org.eclipse.persistence.exceptions.DescriptorException.referenceClassNotSpecified(mapping);
                    }
                    CommitOrderDependencyNode node = getOwner().nodeFor(ownedClass);
                    Vector ownedNodes = withAllSubclasses(node);

                    // I could remove duplicates here, but it's not that big a deal.
                    Helper.addAllToVector(relatedNodes, ownedNodes);
                } else if (mapping.hasInverseConstraintDependency()) {
                    Class ownerClass;
                    ClassDescriptor refDescriptor = mapping.getReferenceDescriptor();
                    if (refDescriptor == null) {
                        refDescriptor = session.getDescriptor(((ForeignReferenceMapping)mapping).getReferenceClass());
                    }
                    ownerClass = refDescriptor.getJavaClass();
                    if (ownerClass == null) {
                        throw org.eclipse.persistence.exceptions.DescriptorException.referenceClassNotSpecified(mapping);
                    }
                    CommitOrderDependencyNode ownerNode = getOwner().nodeFor(ownerClass);
                    Vector ownedNodes = withAllSubclasses(this);

                    // I could remove duplicates here, but it's not that big a deal.
                    Helper.addAllToVector(ownerNode.getRelatedNodes(), ownedNodes);
                }
            }
        }
    }

    /**
     * Add all owned classes for each descriptor through checking the mappings.
     * If I have a foreign mapping with a constraint dependency, then add it
     * If I'm related to a class, I'm related to all its subclasses and superclasses.
     * If my superclass is related to a class, I'm related to it.
     */
    public void recordSpecifiedDependencies() {
        for (Enumeration constraintsEnum = getDescriptor().getConstraintDependencies().elements();
                 constraintsEnum.hasMoreElements();) {
            Class ownedClass = (Class)constraintsEnum.nextElement();
            CommitOrderDependencyNode node = getOwner().nodeFor(ownedClass);
            Vector ownedNodes = withAllSubclasses(node);

            // I could remove duplicates here, but it's not that big a deal.
            Helper.addAllToVector(relatedNodes, ownedNodes);
        }
    }

    public void setDiscoveryTime(int time) {
        discoveryTime = time;
    }

    public void setFinishingTime(int time) {
        finishingTime = time;
    }

    public void setPredecessor(CommitOrderDependencyNode n) {
        predecessor = n;
    }

    @Override
    public String toString() {
        if (descriptor == null) {
            return ToStringLocalization.buildMessage("empty_commit_order_dependency_node", null);
        } else {
            Object[] args = { descriptor };
            return ToStringLocalization.buildMessage("node", args);
        }
    }

    public void visit() {
        //Visit this node as part of a topological sort
        int startTime;
        markInProgress();
        startTime = getOwner().getNextTime();
        setDiscoveryTime(startTime);

        for (Enumeration e = getRelatedNodes().elements(); e.hasMoreElements();) {
            CommitOrderDependencyNode node = (CommitOrderDependencyNode)e.nextElement();
            if (node.hasNotBeenVisited()) {
                node.setPredecessor(this);
                node.visit();
            }
            if (node.getPredecessor() == null) {
                node.setPredecessor(this);
            }
        }

        markVisited();
        setFinishingTime(getOwner().getNextTime());
    }

    // Return an enumeration of all mappings for my descriptor, including those inherited
    public Vector withAllSubclasses(CommitOrderDependencyNode node) {
        Vector results = new Vector();
        results.addElement(node);

        if (node.getDescriptor().hasInheritance()) {
            InheritancePolicy policy = node.getDescriptor().getInheritancePolicy();

            // For bug 3019934 replace getChildDescriptors with getAllChildDescriptors.
            List<ClassDescriptor> childDescriptors = new ArrayList<>();
            childDescriptors.addAll(policy.getAllChildDescriptors());

            // Sort Child Descriptors before adding them to related nodes.
            Collections.sort(childDescriptors, new DescriptorCompare());

            for (ClassDescriptor child : childDescriptors) {
                results.add(getOwner().nodeFor(child));
            }
        }
        return results;
    }
}
