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

import com.atlassian.bitbucket.test.DefaultFuncTestData;
import com.atlassian.fugue.Pair;
import com.jayway.restassured.RestAssured;
import it.com.atlassian.bitbucket.integrity.BaseIntegrityTest;
import it.com.atlassian.bitbucket.integrity.IntegrityTestConstants;
import it.com.atlassian.bitbucket.integrity.annotation.Ahead;
import it.com.atlassian.bitbucket.integrity.annotation.Behind;
import org.junit.Assert;
import org.junit.Test;
import org.springframework.http.HttpStatus;

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


public class RepositoryIntegrityTest extends BaseIntegrityTest {

    @Behind
    @Test
    public void testMissingRepositoriesHasBeenCreated() throws Exception {
        checkDefaultBranchExists(getBranchesDefaultRestEndpoint(
                IntegrityTestConstants.RepositoryConstants.PROJECT,
                IntegrityTestConstants.RepositoryConstants.REPO_OK), HttpStatus.OK,
                Pair.pair("id", "refs/heads/master"));

        checkDefaultBranchExists(getBranchesDefaultRestEndpoint(
                IntegrityTestConstants.RepositoryConstants.PROJECT, IntegrityTestConstants.RepositoryConstants.REPO_MISSING), HttpStatus.NOT_FOUND,
                Pair.pair("errors[0].exceptionName", "com.atlassian.bitbucket.repository.NoSuchRepositoryException"));

        checkDefaultBranchExists(getBranchesDefaultRestEndpoint(
                IntegrityTestConstants.RepositoryConstants.PROJECT, IntegrityTestConstants.RepositoryConstants.REPO_EXTRA), HttpStatus.NOT_FOUND,
                Pair.pair("errors[0].exceptionName", "com.atlassian.bitbucket.repository.NoDefaultBranchException"));
    }

    @Ahead
    @Test
    public void testOnlyDbKnownRepositoriesAreAccessible() {
        checkDefaultBranchExists(getBranchesDefaultRestEndpoint(
                IntegrityTestConstants.RepositoryConstants.PROJECT,
                IntegrityTestConstants.RepositoryConstants.REPO_OK), HttpStatus.OK,
                Pair.pair("id", "refs/heads/master"));

        checkDefaultBranchExists(getBranchesDefaultRestEndpoint(
                IntegrityTestConstants.RepositoryConstants.PROJECT,
                IntegrityTestConstants.RepositoryConstants.REPO_MISSING), HttpStatus.NOT_FOUND,
                Pair.pair("errors[0].exceptionName", "com.atlassian.bitbucket.repository.NoDefaultBranchException"));

        checkDefaultBranchExists(getBranchesDefaultRestEndpoint(
                IntegrityTestConstants.RepositoryConstants.PROJECT,
                IntegrityTestConstants.RepositoryConstants.REPO_EXTRA), HttpStatus.NOT_FOUND,
                Pair.pair("errors[0].exceptionName", "com.atlassian.bitbucket.repository.NoSuchRepositoryException"));
    }

    private void checkDefaultBranchExists(String defaultBranchRestUrl,
                                          HttpStatus statusCode,
                                          Pair<String, String> body) {
        String result = RestAssured.expect()
                    .statusCode(statusCode.value())
                .given()
                    .auth().preemptive()
                    .basic(DefaultFuncTestData.getAdminUser(), DefaultFuncTestData.getAdminPassword())
                    .contentType(JSON)
                .when()
                    .get(defaultBranchRestUrl)
                .then()
                    .log().ifError()
                .extract()
                    .jsonPath().getString(body.left());

        Assert.assertThat(result, equalTo(body.right()));
    }

    private String getBranchesDefaultRestEndpoint(String projectKey, String repoSlug) {
        return INSTANCE.getBaseUrl().concat("/rest/api/latest/projects/" + projectKey + "/repos/" + repoSlug + "/branches/default");
    }
}
