package com.atlassian.bitbucket.test;

import com.atlassian.bitbucket.async.AsyncTestUtils;
import com.atlassian.bitbucket.async.WaitCondition;
import com.atlassian.bitbucket.content.DiffSegmentType;
import com.atlassian.bitbucket.test.rest.comment.RestCommentUtils;
import com.jayway.restassured.RestAssured;
import com.jayway.restassured.http.ContentType;
import com.jayway.restassured.response.Response;
import net.sf.json.JSONObject;
import org.hamcrest.Description;
import org.junit.rules.ExternalResource;

import static com.atlassian.bitbucket.test.rest.ResponseMatchers.*;
import static org.hamcrest.Matchers.anyOf;

public final class CommitCommentTestHelper extends ExternalResource {

    private final String projectKey;
    private final String repositorySlug;
    private final String commitHash;

    public CommitCommentTestHelper(String projectKey, String repositorySlug, String commitHash) {
        this.projectKey = projectKey;
        this.repositorySlug = repositorySlug;
        this.commitHash = commitHash;
    }


    public void deleteCommitCommentAndWait(long commentID, int commentVersion) throws Exception {
        deleteCommitCommentAndWait(commentID, commentVersion, 2500L);
    }

    public void deleteCommitCommentAndWait(long commentID, int commentVersion, long maxWaitTime) throws Exception {
        final String url = DefaultFuncTestData.getRestURL() + "/projects/" + projectKey + "/repos/" + repositorySlug
                + "/commits/" + commitHash + "/comments/" + commentID + "?version=" + commentVersion;
        RestAssured.expect()
                .statusCode(anyOf(accepted(), noContent()))
                .given()
                .auth().preemptive().basic(DefaultFuncTestData.getAdminUser(), DefaultFuncTestData.getAdminPassword())
                .when()
                .delete(url);

        AsyncTestUtils.waitFor(new WaitCondition() {

            @Override
            public void describeFailure(Description description) throws Exception {
                description.appendText(projectKey + "/" + repositorySlug + ": Comment " + commentID +
                        " on commit " + commitHash + " was not deleted");
            }

            @Override
            public boolean test() {
                Response response = RestAssured
                        .given()
                        .auth().preemptive().basic(DefaultFuncTestData.getAdminUser(), DefaultFuncTestData.getAdminPassword())
                        .when()
                        .get(url);
                return notFound().matches(response.getStatusCode());
            }
        }, maxWaitTime);
    }

    public int addCommitComment(String commentText, String filePath, int lineNo, DiffSegmentType segmentType,
                                String username, String password) {
        final String url = DefaultFuncTestData.getRestURL() + "/projects/" + projectKey + "/repos/" + repositorySlug
                + "/commits/" + commitHash + "/comments";

        JSONObject body = RestCommentUtils.createLineBody(commentText, filePath, filePath, lineNo, segmentType);

        Response response = RestAssured
                .given()
                .auth().preemptive().basic(username, password)
                .body(body).contentType(ContentType.JSON)
                .when()
                .post(url);

        return response.jsonPath().getInt("id");
    }
}
