package com.atlassian.stash.internal.comment.like.rest;

import com.atlassian.bitbucket.rest.RestErrors;
import com.atlassian.bitbucket.rest.user.RestApplicationUser;
import com.atlassian.bitbucket.rest.util.ResourcePatterns;
import com.atlassian.bitbucket.rest.util.RestUtils;
import com.atlassian.plugins.rest.common.security.AnonymousAllowed;
import com.atlassian.stash.internal.comment.like.InternalCommentLikeService;
import com.atlassian.bitbucket.pull.PullRequest;
import com.atlassian.bitbucket.pull.PullRequestService;
import com.atlassian.bitbucket.repository.Repository;
import com.atlassian.bitbucket.util.PageRequest;
import com.sun.jersey.spi.resource.Singleton;

import javax.ws.rs.*;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

import static com.atlassian.bitbucket.rest.util.ResourcePatterns.COMMENT_ID;
import static com.atlassian.bitbucket.rest.util.ResourcePatterns.PULL_REQUEST_ID;
import static com.atlassian.stash.internal.comment.like.rest.CommentLikeResourcePatterns.COMMENT_LIKE_URI;

@AnonymousAllowed
@Path(ResourcePatterns.PULL_REQUEST_URI + COMMENT_LIKE_URI)
@Consumes(MediaType.APPLICATION_JSON)
@Produces(RestUtils.APPLICATION_JSON_UTF8)
@Singleton
public class PullRequestCommentLikeResource extends AbstractCommentLikeResource {

    private final PullRequestService pullRequestService;

    public PullRequestCommentLikeResource(InternalCommentLikeService commentLikeService,
                                          PullRequestService pullRequestService) {
        super(commentLikeService);
        this.pullRequestService = pullRequestService;
    }

    /**
     * Get a page of users who liked a pull request comment in the specified repository, identified by
     * <code>pullRequestId</code> and <code>commentId</code>.
     * <p>
     * The authenticated user must have the <strong>REPO_READ</strong> (or higher) permission for the specified
     * repository to access this resource.
     *
     * @response.representation.200.mediaType application/json
     * @response.representation.200.example {@link RestApplicationUser#PAGE_EXAMPLE}
     * @response.representation.200.doc Page of users who liked the specified comment
     *
     * @response.representation.401.mediaType application/json
     * @response.representation.401.qname errors
     * @response.representation.401.example {@link RestErrors#EXAMPLE}
     * @response.representation.401.doc The currently authenticated user does not have sufficient permission
     * (<code>REPO_READ</code>) to query the comment likes
     *
     * @response.representation.404.mediaType application/json
     * @response.representation.404.qname errors
     * @response.representation.404.example {@link RestErrors#EXAMPLE}
     * @response.representation.404.doc The specified repository, pull request or comment does not exist
     */
    @GET
    public Response getLikers(@Context Repository repository, @PathParam(PULL_REQUEST_ID) long pullRequestId,
                              @PathParam(COMMENT_ID) long commentId, @Context PageRequest pageRequest) {

        return getLikers(repository,
                pullRequestService.getComment(repository.getId(), pullRequestId, commentId),
                pageRequest);
    }

    /**
     * Like a pull request comment in the specified repository, identified by <code>pullRequestId</code> and
     * <code>commentId</code>. The like will be recorded against the requesting user.
     * <p>
     * The authenticated user must have the <strong>REPO_READ</strong> (or higher) permission for the specified
     * repository to access this resource.
     *
     * @response.representation.204.doc No content response indicating that the request succeeded
     *
     * @response.representation.400.mediaType application/json
     * @response.representation.400.qname errors
     * @response.representation.400.example {@link RestErrors#EXAMPLE}
     * @response.representation.400.doc The currently authenticated user is the comment author
     *
     * @response.representation.401.mediaType application/json
     * @response.representation.401.qname errors
     * @response.representation.401.example {@link RestErrors#EXAMPLE}
     * @response.representation.401.doc The currently authenticated user does not have sufficient permission
     * (<code>REPO_READ</code>).
     *
     * @response.representation.404.mediaType application/json
     * @response.representation.404.qname errors
     * @response.representation.404.example {@link RestErrors#EXAMPLE}
     * @response.representation.404.doc The specified repository, pull request or comment does not exist
     */
    @POST
    public Response like(@Context Repository repository, @Context PullRequest pullRequest,
                         @PathParam(COMMENT_ID) long commentId) {

        return like(repository, pullRequestService.getComment(repository.getId(), pullRequest.getId(), commentId));
    }

    /**
     * Unlike a pull request comment in the specified repository, identified by <code>pullRequestId</code> and
     * <code>commentId</code>.
     * <p>
     * The authenticated user must have the <strong>REPO_READ</strong> (or higher) permission for the specified
     * repository to access this resource.
     *
     * @response.representation.204.doc No content response indicating that the request succeeded
     *
     * @response.representation.400.mediaType application/json
     * @response.representation.400.qname errors
     * @response.representation.400.example {@link RestErrors#EXAMPLE}
     * @response.representation.400.doc The currently authenticated user is the comment author
     *
     * @response.representation.401.mediaType application/json
     * @response.representation.401.qname errors
     * @response.representation.401.example {@link RestErrors#EXAMPLE}
     * @response.representation.401.doc The currently authenticated user does not have sufficient permission
     * (<code>REPO_READ</code>)
     *
     * @response.representation.404.mediaType application/json
     * @response.representation.404.qname errors
     * @response.representation.404.example {@link RestErrors#EXAMPLE}
     * @response.representation.404.doc The specified repository, pull request or comment does not exist
     */
    @DELETE
    public Response unlike(@Context Repository repository, @Context PullRequest pullRequest,
                         @PathParam(COMMENT_ID) long commentId) {

        return unlike(repository, pullRequestService.getComment(repository.getId(), pullRequest.getId(), commentId));
    }
}
