package it.com.atlassian.stash.notification;

import com.atlassian.bitbucket.smtp.MailTestUtils;
import com.atlassian.bitbucket.smtp.SmtpServer;
import com.atlassian.bitbucket.test.*;
import com.atlassian.bitbucket.test.rest.comment.RestCommentUtils;
import com.atlassian.bitbucket.permission.Permission;
import it.com.atlassian.stash.BaseRestTest;
import org.junit.After;
import org.junit.Before;
import org.junit.BeforeClass;

public abstract class AbstractPullRequestNotificationTest extends BaseRestTest {

    protected static final String PROJECT = DefaultFuncTestData.getProject1();
    protected static final String REPO = DefaultFuncTestData.getProject1Repository1();
    protected static final String PR_AUTHOR = "pr-author";
    protected static final String IMMEDIATE_REVIEWER = "immediate-reviewer";
    protected static final String BATCHED_REVIEWER = "batched-reviewer";
    protected static final String PR_AUTHOR_EMAIL = PR_AUTHOR + "@example.com";
    protected static final String IMMEDIATE_REVIEWER_EMAIL = IMMEDIATE_REVIEWER + "@example.com";
    protected static final String BATCHED_REVIEWER_EMAIL = BATCHED_REVIEWER + "@example.com";
    protected static final String MAIL_SERVER_EMAIL = "test-comment-actions@example.com";

    protected static long pullRequestId;

    protected SmtpServer smtpServer;

    @BeforeClass
    public static void setUpTestData() {
        /*
         * There are 3 users:
         * Immediate Reviewer has the notification mode set to Immediate
         * Batched Reviewer has the notification mode set to Batched
         * PR Author has notification set to batched by default but can be changed for testing
         */
        TestContext context = getClassTestContext();

        // Get the test context, add the three users and their permissions
        context.user(PR_AUTHOR, PR_AUTHOR, PR_AUTHOR, PR_AUTHOR_EMAIL)
                .user(IMMEDIATE_REVIEWER, IMMEDIATE_REVIEWER, IMMEDIATE_REVIEWER, IMMEDIATE_REVIEWER_EMAIL)
                .user(BATCHED_REVIEWER, BATCHED_REVIEWER, BATCHED_REVIEWER, BATCHED_REVIEWER_EMAIL)
                .repositoryPermission(PROJECT, REPO, PR_AUTHOR, Permission.REPO_READ)
                .repositoryPermission(PROJECT, REPO, IMMEDIATE_REVIEWER, Permission.REPO_READ)
                .repositoryPermission(PROJECT, REPO, BATCHED_REVIEWER, Permission.REPO_READ);

        // Create a pull request by the author
        PullRequestTestHelper pullRequest = context.pullRequest(
                new PullRequestTestHelper.Builder(PR_AUTHOR, PR_AUTHOR, "Test PR", "",
                        PROJECT, REPO, DefaultFuncTestData.getProject1Repository1BasicBranchingBranch(),
                        PROJECT, REPO, DefaultFuncTestData.getProject1Repository1MasterBranch()));
        pullRequestId = pullRequest.getId();

        // Add the reviewers to the pull request
        pullRequest.addReviewers(IMMEDIATE_REVIEWER, BATCHED_REVIEWER);

        // Set up the notification modes
        setUserModeImmediate(IMMEDIATE_REVIEWER);
        //setUserModeBatched(PR_AUTHOR);
        setUserModeBatched(BATCHED_REVIEWER);

        // Set up the mail server
        context.mailConfig(MailTestUtils.getSmtpConfiguration(), MAIL_SERVER_EMAIL);
    }

    @Before
    public void setUpMailServer() {
        // the SMTP server is started and stopped of each test for isolation
        smtpServer = MailTestUtils.createNewSMTPServer();
        smtpServer.start();
    }

    @After
    public void tearDownMailServer() {
        smtpServer.stop();
    }

    public static long addComment(String user, String text) {
        return PullRequestRestTestHelper.createComment(PROJECT, REPO, pullRequestId, user, user,
                RestCommentUtils.createBody(text), text);
    }

    public static void likeComment(String user, long commentId) {
        new PullRequestCommentLikeHelper(PROJECT, REPO, pullRequestId).likeComment(commentId, user);
    }

    public static void unlikeComment(String user, long commentId) {
        new PullRequestCommentLikeHelper(PROJECT, REPO, pullRequestId).unlikeComment(commentId, user);
    }

    public static void setUserModeBatched(String user) {
        UserTestHelper.setNotificationSendMode(user, UserTestHelper.SEND_MODE_BATCHED);
    }

    public static void setUserModeImmediate(String user) {
        UserTestHelper.setNotificationSendMode(user, UserTestHelper.SEND_MODE_IMMEDIATE);
    }

}
