/*
 * Copyright (c) 1998, 2019 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 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;
    }
}
