package com.atlassian.bitbucket.compare;

import com.atlassian.bitbucket.commit.Commit;
import com.atlassian.bitbucket.commit.CommitCallback;
import com.atlassian.bitbucket.content.ChangeCallback;
import com.atlassian.bitbucket.content.DiffContentCallback;

import javax.annotation.Nonnull;

/**
 * Compares two commits. Commits can be specified by {@link Commit#getId ID} or by branch or
 * tag name. For SCMs which have a concept of a short name, such as Git with its shortened SHA-1s and unqualified ref
 * names, the <i>fully-qualified</i> version should be used wherever possible to avoid ambiguity.
 */
public interface CompareService {

    /**
     * Streams changes contained on the {@link CompareRequest#getFromRef() from ref} but not on the
     * {@link CompareRequest#getToRef() to ref}.
     * <p>
     * <b>Note</b>: Change information is not paged. Instead, it is bounded by a hard cap specified by the
     * property {@code page.max.changes}. See the <a href="https://confluence.atlassian.com/x/oAqmEQ">configuration
     * documentation</a> for more information.
     *
     * @param request  describes the refs to compare
     * @param callback a callback for receiving the changes
     */
    void streamChanges(@Nonnull CompareRequest request, @Nonnull ChangeCallback callback);

    /**
     * Streams commits reachable from the {@link CompareRequest#getFromRef() from ref} but not reachable from the
     * {@link CompareRequest#getToRef() to ref}.
     *
     * @param request  describes the refs to compare
     * @param callback a callback for receiving the commits
     */
    void streamCommits(@Nonnull CompareRequest request, @Nonnull CommitCallback callback);

    /**
     * Streams the diff of the changes contained on the {@link CompareRequest#getFromRef() from ref} but not on the
     * {@link CompareRequest#getToRef() to ref}.
     * <p>
     * <b>Note</b>: Diff output is not paged. Instead, it is bounded by hard caps specified by the following properties:
     * <ul>
     *     <li>{@code page.max.diff.lines}, specifying the max number of diff lines to output</li>
     *     <li>{@code page.max.source.length}, specifying the max length of each diff line</li>
     * </ul>
     * See the <a href="https://confluence.atlassian.com/x/oAqmEQ">configuration documentation</a> for more information.
     *
     * @param request  describes the refs to compare
     * @param callback a callback for receiving the diff output
     */
    void streamDiff(@Nonnull CompareDiffRequest request, @Nonnull DiffContentCallback callback);

}
