package it.com.atlassian.bitbucket.integrity.pull;

import com.atlassian.bitbucket.test.DefaultFuncTestData;
import com.atlassian.bitbucket.test.PullRequestRestTestHelper;
import com.jayway.restassured.RestAssured;
import com.jayway.restassured.response.Response;
import com.jayway.restassured.response.ValidatableResponse;
import it.com.atlassian.bitbucket.integrity.BaseIntegrityTest;
import it.com.atlassian.bitbucket.integrity.IntegrityTestConstants;
import it.com.atlassian.bitbucket.integrity.IntegrityTestUtils;
import it.com.atlassian.bitbucket.integrity.annotation.Behind;
import it.com.atlassian.bitbucket.integrity.annotation.Ahead;
import org.junit.BeforeClass;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static com.jayway.restassured.http.ContentType.JSON;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertEquals;

public class PullRequestIntegrityTest extends BaseIntegrityTest {

    private static final Logger logger = LoggerFactory.getLogger(PullRequestIntegrityTest.class);

    private static final String INTEGRITY_CHECK_USER = "Integrity Checker";

    @BeforeClass
    public static void runMergedPullRequestCheck() throws Exception {
        String restUrl = INSTANCE.getBaseUrl() + "/admin/integrity-check/merged-pull-requests";
        logger.info("Making REST call to: {}", restUrl);
        Response response = RestAssured
                .given()
                    .auth().preemptive()
                    .basic(DefaultFuncTestData.getAdminUser(), DefaultFuncTestData.getAdminPassword())
                    .contentType("application/json")
                .when()
                    .post(restUrl);

        assertEquals(200, response.getStatusCode());
    }

    @Behind
    @Test
    public void testMergedPullRequestIsInCorrectState() throws Exception {
        assertPullRequestIs("OPEN");
        assertLastActivityIs("REOPENED", INTEGRITY_CHECK_USER);
    }

    @Ahead
    @Test
    public void testMergedPullRequestIsInCorrectStateAhead() {
        assertPullRequestIs("MERGED");
        assertLastActivityIs("MERGED", INTEGRITY_CHECK_USER);
    }

    private void assertLastActivityIs(String activity, String activityAuthor) {
        String activitiesUrl = PullRequestRestTestHelper.getPullRequestURL(IntegrityTestConstants.PR_PROJ,
                IntegrityTestConstants.PR_REPO, IntegrityTestUtils.getValue(INSTANCE, IntegrityTestConstants.PR_TITLE))
                + "/activities";

        getRestResponse(activitiesUrl)
            .body("values[0].action", equalTo(activity))
            .body("values[0].user.displayName", equalTo(activityAuthor));
    }

    private void assertPullRequestIs(String state) {
        String pullRequestUrl = PullRequestRestTestHelper.getPullRequestURL(IntegrityTestConstants.PR_PROJ,
                IntegrityTestConstants.PR_REPO, IntegrityTestUtils.getValue(INSTANCE, IntegrityTestConstants.PR_TITLE));

        getRestResponse(pullRequestUrl)
            .body("state", equalTo(state));
    }

    private ValidatableResponse getRestResponse(String pullRequestUrl) {
        return RestAssured
                .expect()
                    .statusCode(200)
                .given()
                    .auth().preemptive()
                    .basic(DefaultFuncTestData.getAdminUser(), DefaultFuncTestData.getAdminPassword())
                .when()
                    .get(IntegrityTestUtils.urlFor(INSTANCE, pullRequestUrl))
                .then()
                    .contentType(JSON)
                    .log().ifError();
    }
}
