package com.atlassian.stash.internal.task;

import com.atlassian.bitbucket.pull.PullRequestService;
import com.atlassian.bitbucket.pull.PullRequestTaskSearchRequest;
import com.atlassian.bitbucket.task.TaskService;
import com.atlassian.bitbucket.task.Task;
import com.atlassian.bitbucket.task.TaskAnchor;
import com.atlassian.bitbucket.task.TaskCount;
import com.atlassian.bitbucket.util.Page;
import com.atlassian.bitbucket.util.PageRequest;

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

/**
 * Non-public extensions to the {@link TaskService} which are not intended to be available to plugins.
 * <p>
 * Specific versions of these methods for different {@link InternalTaskContext task contexts}
 * are defined in the service providers for those contexts.
 * <p>
 * For instance, {@link PullRequestService#countTasks(PullRequestTaskSearchRequest) countTasks()}
 * and {@link PullRequestService#searchTasks(PullRequestTaskSearchRequest, PageRequest) searchTasks()}
 * perform the equivalent functions for pull request tasks.
 *
 * @since 3.3
 */
public interface InternalTaskService extends TaskService {

    /**
     * Count the total number of tasks for the given search request.
     *
     * @param searchRequest the properties the tasks should match
     * @return the counts for the contexts
     */
    @Nonnull
    TaskCount count(@Nonnull InternalTaskSearchRequest searchRequest);

    /**
     * Checks whether an anchor has one or more tasks.
     *
     * @param anchor the anchor to check
     * @return {@code true} if the anchor has any task
     */
    boolean hasTasks(@Nonnull TaskAnchor anchor);

    /**
     * Count the number of tasks associated with each {@link InternalTaskContext}. The {@link Map} returned will
     * contain a {@link TaskCount} for each given context.
     *
     * @param contexts the set of contexts for whom to return task counts
     * @return the counts for the contexts
     */
    @Nonnull
    <T extends InternalTaskContext> Map<T, TaskCount> countForContexts(@Nonnull Iterable<T> contexts);

    /**
     * Find tasks matching the specified {@link InternalTaskSearchRequest request}.
     *
     * @param searchRequest the properties the tasks should match
     * @param pageRequest a {@link PageRequest page request} to delimit the search
     * @param withProperties  {@code true} to fetch the tasks' properties
     * @return a page of tasks matching the {@code searchRequest}
     */
    @Nonnull
    Page<Task> search(@Nonnull InternalTaskSearchRequest searchRequest, @Nonnull PageRequest pageRequest, boolean withProperties);
}
