package com.atlassian.stash.internal.web.repos.jobs;

import com.atlassian.bitbucket.i18n.I18nService;
import com.atlassian.bitbucket.permission.PermissionService;
import com.atlassian.bitbucket.repository.RefService;
import com.atlassian.bitbucket.repository.Repository;
import com.atlassian.bitbucket.repository.RepositoryService;
import com.atlassian.stash.internal.project.InternalProjectService;
import com.atlassian.stash.internal.pull.rescope.InternalPullRequestRescopeService;
import com.atlassian.stash.internal.pull.rescope.RepositoryRescopeResult;
import com.atlassian.stash.internal.scm.InternalScmService;
import com.atlassian.stash.internal.web.auth.IgnoresXsrf;
import com.atlassian.stash.internal.web.util.RepositoryControllerSupport;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import static org.springframework.web.bind.annotation.RequestMethod.POST;

/**
 * Controller for admin jobs on repositories.
 * <p>
 * This is not a REST resource because it uses internal API and we don't want the methods to be part of our published
 * REST interface.
 *
 * @since 3.7
 */
@RestController
@RequestMapping("/projects/{projectKey}/repos/{repoSlug}/jobs")
public class RepositoryJobController extends RepositoryControllerSupport {

    private final InternalPullRequestRescopeService pullRequestRescopeService;

    @Autowired
    public RepositoryJobController(I18nService i18nService, RefService refService,
                                   PermissionService permissionService, InternalProjectService projectService,
                                   RepositoryService repositoryService, InternalScmService scmService,
                                   InternalPullRequestRescopeService pullRequestRescopeService) {
        super(i18nService, refService, permissionService, projectService, repositoryService, scmService);
        this.pullRequestRescopeService = pullRequestRescopeService;
    }

    /**
     * Rescope all pull requests of a repository.
     * <p>
     * Useful for support when there was a problem with rescoping. This could also be in a REST resource instead, but
     * that would mean we would have to expose an API method for rescoping pull requests.
     */
    @IgnoresXsrf // Is not called from a normal form, so it will not have an XSRF token.
    @RequestMapping(value = "/rescope-pull-requests", method = POST,
            consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<RestRescopeResult> rescopePullRequests(
            @PathVariable("projectKey") String projectKey,
            @PathVariable("repoSlug") String repoSlug,
            @RequestParam(value = "triggerOnly", defaultValue = "false") boolean triggerOnly,
            @RequestBody RestRescopeRequest rescopeRequest) {
        Repository repository = getRepository(projectKey, repoSlug);

        // if triggerOnly is provided, no artificial rescope request should be created. Just rescope based on current
        // rescope requests in the database
        RepositoryRescopeResult result = triggerOnly ?
                pullRequestRescopeService.rescope(repository) :
                pullRequestRescopeService.rescope(repository, rescopeRequest.getBranches());

        RestRescopeResult restResult = new RestRescopeResult(result.getSkippedCount(), result.getErrorCount());
        HttpStatus status = result.hasErrors() ? HttpStatus.INTERNAL_SERVER_ERROR : HttpStatus.OK;
        return new ResponseEntity<>(restResult, status);
    }
}
