package com.atlassian.bitbucket.scm.compare;

import com.atlassian.bitbucket.commit.CommitCallback;
import com.atlassian.bitbucket.compare.CompareDiffRequest;
import com.atlassian.bitbucket.compare.CompareRequest;
import com.atlassian.bitbucket.compare.CompareService;
import com.atlassian.bitbucket.content.ChangeCallback;
import com.atlassian.bitbucket.content.DiffContentCallback;
import com.atlassian.bitbucket.scm.Command;

import javax.annotation.Nonnull;

/**
 * Creates {@link Command commands} which allow comparing arbitrary refs or commits. Each method accepts a set of
 * {@code CommandParameters} which are used to control the command's behaviour and output.
 * <p>
 * <b>Plugin developers</b>: <i>This is probably not the interface you want to use.</i> {@link CompareService}
 * automatically chooses the correct SCM based on the repository, and provides a more stable, compatible API. The
 * documentation for each method on this interface includes a link to the API service method or methods which expose it.
 */
public interface ScmCompareCommandFactory {

    /**
     * @param parameters parameters describing how many changes to stream, and potentially for which paths
     * @param callback   a callback to receive changes
     * @return a command which, when executed, will stream the changes between the
     *         {@link CompareRequest#getFromRef() from ref} and the {@link CompareRequest#getToRef() to ref}
     * @see CompareService#streamChanges(CompareRequest, ChangeCallback)
     */
    @Nonnull
    Command<Void> changes(@Nonnull CompareChangeCommandParameters parameters,
                          @Nonnull ChangeCallback callback);

    /**
     * @param callback a callback to receive commits
     * @return a command which, when executed, will stream the commits that are reachable from
     *         the {@link CompareRequest#getFromRef() from ref} and not reachable from the
     *         {@link CompareRequest#getToRef() to ref}
     * @see CompareService#streamCommits(CompareRequest, CommitCallback)
     */
    @Nonnull
    Command<Void> commits(@Nonnull CommitCallback callback);

    /**
     * @param parameters parameters describing the paths to diff and what should be included in the diffs generated
     * @param callback   a callback to receive the diff
     * @return a command which, when executed, will stream the diff between the
     *         {@link CompareRequest#getFromRef() from ref} and the {@link CompareRequest#getToRef() to ref}
     *         for the specified paths
     * @see CompareService#streamDiff(CompareDiffRequest, DiffContentCallback)
     */
    @Nonnull
    Command<Void> diff(@Nonnull CompareDiffCommandParameters parameters, @Nonnull DiffContentCallback callback);
}
