package com.atlassian.bitbucket.internal.mirroring.upstream.rest;

import com.atlassian.bitbucket.mirroring.upstream.MirrorServer;
import com.atlassian.bitbucket.mirroring.upstream.MirrorService;
import com.atlassian.bitbucket.mirroring.upstream.MirroringUserSettingsService;
import com.atlassian.bitbucket.rest.util.ResponseFactory;
import com.atlassian.bitbucket.rest.util.RestUtils;
import com.atlassian.plugins.rest.common.security.AnonymousAllowed;
import com.sun.jersey.spi.resource.Singleton;

import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.Optional;

@AnonymousAllowed
@Path("account/settings")
@Consumes({MediaType.APPLICATION_JSON})
@Produces({RestUtils.APPLICATION_JSON_UTF8})
@Singleton
public class MirroringUserSettingsResource {

    private final MirrorService mirrorService;
    private final MirroringUserSettingsService mirroringUserSettingsService;

    MirroringUserSettingsResource(MirrorService mirrorService,
                                  MirroringUserSettingsService mirroringUserSettingsService) {

        this.mirrorService = mirrorService;
        this.mirroringUserSettingsService = mirroringUserSettingsService;
    }

    /**
     * Sets the mirror specified by a mirror ID as the current user's preferred mirror
     *
     * @param mirrorId the mirror ID
     *
     * @request.representation.mediaType application/json
     * @request.representation.doc the mirror ID
     *
     * @response.representation.204.mediaType application/json
     * @response.representation.204.doc an empty response indicating that the user setting has been updated
     *
     * @response.representation.404.mediaType application/json
     * @response.representation.404.qname not-found
     * @response.representation.404.doc The mirror could not be found.
     */
    @POST
    @Path("preferred-mirror")
    public Response setPreferredMirrorId(String mirrorId) {
        MirrorServer mirrorServer = mirrorService.getById(mirrorId);

        if (mirrorServer != null) {
            mirroringUserSettingsService.setPreferredMirror(mirrorServer);
            return ResponseFactory.noContent().build();
        } else {
            return ResponseFactory.notFound().build();
        }
    }

    /**
     * Retrieves the current user's preferred mirror server
     *
     * @response.representation.200.mediaType application/json
     * @response.representation.200.example {@link RestMirrorServer#EXAMPLE_ENABLED}
     * @response.representation.200.doc the preferred mirror server
     *
     * @response.representation.404.mediaType application/json
     * @response.representation.404.qname not-found
     * @response.representation.404.doc The user's preferred mirror server could not be found.
     */
    @GET
    @Path("preferred-mirror")
    public Response getPreferredMirrorId() {
        Optional<MirrorServer> mirrorServer = mirroringUserSettingsService.getPreferredMirror();

        if (mirrorServer.isPresent()) {
            return ResponseFactory.ok()
                    .entity(new RestMirrorServer(mirrorServer.get()))
                    .build();
        } else {
            return ResponseFactory.notFound().build();
        }
    }

    /**
     * Removes the current user's preferred mirror
     *
     * @response.representation.204.mediaType application/json
     * @response.representation.204.doc an empty response indicating that the user setting has been updated
     */
    @DELETE
    @Path("preferred-mirror")
    public Response deletePreferredMirrorId() {
        mirroringUserSettingsService.removePreferredMirror();
        return ResponseFactory.noContent().build();
    }
}
