package com.atlassian.stash.internal.pull.rescope;

import com.atlassian.bitbucket.commit.Commit;
import com.atlassian.bitbucket.pull.RescopeDetails;
import com.atlassian.stash.internal.pull.InternalPullRequest;
import com.atlassian.stash.internal.pull.InternalPullRequestRescopeActivity;

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

/**
 * Describes a component which processes {@link InternalPullRequestRescopeActivity rescope activities} to calculate
 * and store details for the {@link com.atlassian.stash.internal.pull.InternalPullRequestRescopeCommit commits} they
 * add and remove. As an optimization, multiple activities may be processed in a single call.
 * <p>
 * When new {@link InternalPullRequestRescopeActivity activities} are created, they may be
 * {@link #queue(InternalPullRequestRescopeActivity) queued} for background processing. That allows their details to
 * be more aggressively calculated and stored, to reduce lag when viewing pull request overviews.
 * <p>
 * Note: The {@code RescopeProcessor} is <i>not</i> guaranteed to set {@link RescopeDetails
 * rescope details} on processed {@link InternalPullRequestRescopeActivity activities}. If commits added and removed
 * have already been {@link InternalPullRequestRescopeActivity#isPrecalculated() precalculated}, it is left to the
 * <i>caller</i> to flesh them out as full {@link Commit commits} and build up
 * {@link RescopeDetails details} instances.
 *
 * @since 2.5
 */
public interface RescopeProcessor {

    /**
     * Processes a single {@link InternalPullRequestRescopeActivity rescope activity}, calculating its added and
     * removed commits if they are not already available.
     *
     * @param activity the activity to process
     */
    void process(@Nonnull InternalPullRequestRescopeActivity activity);

    /**
     * Processes a collection of {@link InternalPullRequestRescopeActivity rescope activities} for a <i>single
     * {@link InternalPullRequest pull request}</i> in one shot. This bulk processing allows the implementation
     * to (potentially) optimize calculating the added and removed commits, as well as persisting them.
     *
     * @param pullRequest the pull request to which <i>all</i> activities belong
     * @param activities  the activities to process
     */
    void processAll(@Nonnull InternalPullRequest pullRequest,
                    @Nonnull List<InternalPullRequestRescopeActivity> activities);

    /**
     * Queues the provided {@link InternalPullRequestRescopeActivity rescope activity} for background processing,
     * allowing the system to {@link InternalPullRequestRescopeActivity#isPrecalculated() precalculate} its added
     * and removed commits before it is ever viewed. This improves the responsiveness of the pull request overview
     * tab, which may contain a large number of rescopes (many of which do not add or remove any commits).
     *
     * @param activity the activity to queue for background processing
     */
    void queue(@Nonnull InternalPullRequestRescopeActivity activity);
}
