package com.atlassian.bitbucket.test.rest.mirror;

import com.atlassian.bitbucket.test.rest.server.stub.mirror.StubMirror;
import com.atlassian.bitbucket.test.DefaultFuncTestData;
import com.jayway.restassured.response.Response;

import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response.Status;

import static com.atlassian.bitbucket.test.StatusCodesTestHelper.matching;
import static com.atlassian.bitbucket.test.DefaultFuncTestData.getAdminPassword;
import static com.atlassian.bitbucket.test.DefaultFuncTestData.getAdminUser;
import static com.jayway.restassured.RestAssured.given;
import static javax.ws.rs.core.Response.Status.*;

public class MirroringRequestHelper {
    public static Response acceptRequest(int id) {
        return acceptRequest(id, OK);
    }

    public static Response acceptRequest(int id, Status expectedStatus) {
        return given()
                .auth().preemptive().basic(getAdminUser(), getAdminPassword())
                .contentType(MediaType.APPLICATION_JSON)
                .expect()
                .statusCode(expectedStatus.getStatusCode())
                .log().ifValidationFails()
                .when().post(getMirroringRequestAcceptUrl(id));
    }


    public static Response createMirroringRequest(final String mirrorId, final String baseUrl,
                                                  final String descriptorUrl,
                                                  final Status status) {
        return given()
                .contentType(MediaType.APPLICATION_JSON)
                .body(newMirroringRequest(mirrorId, baseUrl, descriptorUrl))
                .log().ifValidationFails()
                .expect()
                .statusCode(status.getStatusCode())
                .log().ifValidationFails()
                .when().post(getMirroringRequestsUrl());
    }

    public static Response deleteRequest(int id) {
        return deleteRequest(id, NO_CONTENT);
    }

    public static Response deleteRequest(int id, Status... statuses) {
        return given()
                .auth().preemptive().basic(getAdminUser(), getAdminPassword())
                .contentType(MediaType.APPLICATION_JSON)
                .log().ifValidationFails()
                .expect().statusCode(matching(statuses))
                .log().ifValidationFails()
                .when().delete(getMirroringRequestUrl(id));
    }

    public static String getAddOnUrl(String mirrorId) {
        return DefaultFuncTestData.getRestURL("plugins", "latest") + "/" + mirrorId.toLowerCase() + "-key";
    }

    public static String getAddOnUrl(StubMirror mirror) {
        return getAddOnUrl(mirror.getAddonKey());
    }

    public static String getMirroringRequestsUrl() {
        return DefaultFuncTestData.getRestURL("mirroring", "latest") + "/requests";
    }

    public static String getMirroringRequestUrl(Object requestId) {
        return getMirroringRequestsUrl() + "/" + String.valueOf(requestId);
    }

    public static String getMirroringRequestAcceptUrl(int id) {
        return getMirroringRequestUrl(id) + "/accept";
    }

    public static String getMirroringRequestRejectUrl(int id) {
        return getMirroringRequestUrl(id) + "/reject";
    }

    public static int getIdFromResponse(Response response) {
        return response.getBody().jsonPath().getInt("id");
    }

    public static String newMirroringRequest(String mirrorId, String baseUrl, String descriptorUrl) {
        return String.format("{" +
                "\"mirrorId\": \"%s\", " +
                "\"mirrorName\": \"%s\", " +
                "\"mirrorBaseUrl\": \"%s\", " +
                "\"productType\": \"test-mirror\", " +
                "\"productVersion\": \"none\", " +
                "\"addonDescriptorUri\": \"%s\"" +
                "}", mirrorId, mirrorId, baseUrl, descriptorUrl);
    }

    public static Response rejectRequest(int id) {
        return rejectRequest(id, OK);
    }

    public static Response rejectRequest(int id, Status expectedStatus) {
        return given()
                .auth().preemptive().basic(getAdminUser(), getAdminPassword())
                .contentType(MediaType.APPLICATION_JSON)
                .log().ifValidationFails()
                .expect()
                .statusCode(expectedStatus.getStatusCode())
                .log().ifValidationFails()
                .when().post(getMirroringRequestRejectUrl(id));
    }

    public static Response retrieveRequest(int id) {
        return given()
                .auth().preemptive().basic(getAdminUser(), getAdminPassword())
                .contentType(MediaType.APPLICATION_JSON)
                .log().ifValidationFails()
                .expect()
                .statusCode(OK.getStatusCode())
                .log().ifValidationFails()
                .when().get(getMirroringRequestUrl(id));
    }
}
