package com.atlassian.stash.internal.scm.git.pull;

import com.atlassian.bitbucket.pull.*;
import com.atlassian.bitbucket.repository.NoSuchRepositoryException;
import com.atlassian.bitbucket.i18n.I18nService;
import com.atlassian.bitbucket.repository.Repository;
import com.atlassian.bitbucket.repository.RepositoryService;
import com.atlassian.bitbucket.util.Page;
import com.atlassian.bitbucket.util.PageProvider;
import com.atlassian.bitbucket.util.PageRequest;
import com.atlassian.bitbucket.util.PagedIterable;
import com.google.common.collect.ImmutableSet;

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

/**
 * @since 2.9
 */
public class DefaultGitPullRequestSupplier implements GitPullRequestSupplier {

    private final I18nService i18nService;
    private final PullRequestService pullRequestService;
    private final RepositoryService repositoryService;

    public DefaultGitPullRequestSupplier(I18nService i18nService, PullRequestService pullRequestService,
                                         RepositoryService repositoryService) {
        this.i18nService = i18nService;
        this.pullRequestService = pullRequestService;
        this.repositoryService = repositoryService;
    }

    @Nonnull
    @Override
    public Set<Long> getOpenIds(final int repositoryId) {
        PagedIterable<Long> pullRequestIds = new PagedIterable<>(new PageProvider<Long>() {

            @Override
            public Page<Long> get(PageRequest request) {
                return pullRequestService.search(new PullRequestSearchRequest.Builder()
                        .toRepositoryId(repositoryId)
                        .state(PullRequestState.OPEN)
                        .build(), request).transform(PullRequest.TO_ID);
            }
        }, 50);

        return ImmutableSet.copyOf(pullRequestIds);
    }

    @Nonnull
    @Override
    public PullRequest getById(int repositoryId, long pullRequestId) {
        PullRequest pullRequest = pullRequestService.getById(repositoryId, pullRequestId);
        if (pullRequest == null) {
            Repository repository = repositoryService.getById(repositoryId);
            if (repository == null) {
                throw new NoSuchRepositoryException(
                        i18nService.createKeyedMessage("bitbucket.git.pullrequest.nosuchrepository",
                            repositoryId),
                        null);
            }
            throw new NoSuchPullRequestException(
                    i18nService.createKeyedMessage("bitbucket.git.pullrequest.nosuchpullrequest",
                            pullRequestId, repository.getProject().getKey(), repository.getSlug()));
        }

        return pullRequest;
    }
}
