package com.atlassian.bitbucket.integration.jira;

import com.atlassian.bitbucket.commit.Changeset;
import com.atlassian.bitbucket.commit.Commit;
import com.atlassian.bitbucket.content.Change;
import com.atlassian.bitbucket.pull.PullRequest;
import com.atlassian.bitbucket.util.Page;
import com.atlassian.bitbucket.util.PageRequest;

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

/**
 * Service used to retrieve and modify JIRA issue to commit mappings
 */
public interface JiraIssueService {

    /**
     * Retrieves changesets for commits that are linked to the specified JIRA issue. This method performs a
     * cross-repository query, but will only return commits in repositories that the user is permitted to see.
     * If a commit exists in multiple repositories, an arbitrary repository is chosen.
     * <p>
     * For each matching commit that the user is allowed to see, the first {@code maxChanges} are retrieved
     * and used to build a {@link Changeset}.
     * 
     * @param issueKey    the issue key
     * @param maxChanges  the maximum number of {@link Change changes} to
     *                    return for each changeset
     * @param pageRequest specifies the offset and limit for the paging of changesets
     * @return a {@link Page} of {@link Changeset} that are linked to the requested JIRA issue, which may be
     *         empty but never {@code null}
     */
    @Nonnull
    Page<Changeset> getChangesetsForIssue(@Nonnull String issueKey, int maxChanges, @Nonnull PageRequest pageRequest);

    /**
     * Retrieves JIRA issues that are associated with the specified pull request. Issues are associated with the
     * pull request if they appear in:
     * <ul>
     *     <li>messages for any of the commits on the pull request</li>
     *     <li>the pull request's {@link PullRequest#getTitle title}</li>
     *     <li>the name of the pull request's {@link PullRequest#getFromRef() source branch}</li>
     * </ul>
     * <p>
     * By default, issues are only drawn from the first 100 commits on the pull request. If the pull request
     * includes more than 100 commits, some issues may not be returned. That limit may be raised by adjusting
     * {@code plugin.jira-integration.pullrequest.attribute.commits.max}.
     *
     * @param repositoryId  the ID of the repository to which the pull request will be merged
     * @param pullRequestId the ID of the pull request within the repository
     * @return a {@link Set} of {@link JiraIssue}s, which may be empty but not null
     */
    @Nonnull
    Set<JiraIssue> getIssuesForPullRequest(int repositoryId, long pullRequestId);

    /**
     * Retrieves JIRA issues associated with any of the specified commits.
     * <p>
     * By default, issues are only drawn from the first 100 commits in the provided set. If the set contains
     * more than 100 commit IDs, some issues may not be returned. That limit may be raised by adjusting
     * {@code plugin.jira-integration.pullrequest.attribute.commits.max}.
     *
     * @param commitIds a set of <i>full</i> {@link Commit#getId() commit IDs}; partial
     *                  IDs or display IDs <i>will not match</i>
     * @return a {@link Set} of {@link JiraIssue}s, which may be empty but not null
     */
    @Nonnull
    Set<JiraIssue> getIssuesForCommits(Set<String> commitIds);
}
