package com.atlassian.bitbucket.commit.graph;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;

import javax.annotation.Nonnull;
import java.util.Iterator;
import java.util.List;

/**
 * A graph callback which is able to batch multiple graph callbacks in a single traversal. The traversal ends when all
 * delegate callbacks have finished.
 */
public class BatchingTraversalCallback extends TraversalCallback {

    private final List<TraversalCallback> delegates;
    private final List<TraversalCallback> activeDelegates;

    public BatchingTraversalCallback(List<? extends TraversalCallback> delegates) {
        this.delegates = ImmutableList.copyOf(delegates);
        this.activeDelegates = Lists.newArrayList(this.delegates);
    }

    @Override
    public void onEnd(@Nonnull TraversalSummary summary) {
        for (TraversalCallback delegate : delegates) {
            delegate.onEnd(summary);
        }
    }

    @Override
    public TraversalStatus onNode(@Nonnull CommitGraphNode node) {
        for (Iterator<TraversalCallback> it = activeDelegates.iterator(); it.hasNext();) {
            if (it.next().onNode(node) == TraversalStatus.FINISH) {
                it.remove();
            }
        }

        return activeDelegates.isEmpty() ?  TraversalStatus.FINISH : TraversalStatus.CONTINUE;
    }

    @Override
    public void onStart(@Nonnull TraversalContext context) {
        for (TraversalCallback delegate : delegates) {
            delegate.onStart(context);
        }
    }
}
