package com.atlassian.stash.internal.comment.like.notification;

import com.atlassian.bitbucket.comment.Comment;
import com.atlassian.bitbucket.user.TestApplicationUser;
import com.atlassian.stash.internal.comment.like.DefaultCommentLikeService;
import com.atlassian.bitbucket.pull.PullRequest;
import com.atlassian.bitbucket.pull.PullRequestRef;
import com.atlassian.bitbucket.repository.Repository;
import com.atlassian.bitbucket.user.ApplicationUser;
import com.atlassian.bitbucket.permission.PermissionValidationService;
import com.google.common.collect.ImmutableMap;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

import java.util.Collections;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.when;

@RunWith(MockitoJUnitRunner.class)
public class UserHasLikedCommentConditionTest extends AbstractCommentConditionTest {

    @Mock
    private Comment likedComment;

    @Mock
    private Comment notLikedComment;

    @Mock
    protected PermissionValidationService permissionValidationService;

    @Mock
    protected PullRequest pullRequest;

    @Mock
    private PullRequestRef pullRequestRef;

    @Mock
    private Repository repository;

    @InjectMocks
    protected UserHasLikedCommentCondition condition;

    @InjectMocks
    protected DefaultCommentLikeService commentLikeService;

    @Before
    public void setUpCurrentUser() {
        stashAuthenticationContext.setCurrentUser(stashUser);
    }

    @Before
    public void getPlumbingUp() {
        when(pullRequest.getToRef()).thenReturn(pullRequestRef);
        when(pullRequestRef.getRepository()).thenReturn(repository);
    }

    @Test
    public void testInit() throws Exception {
        condition.init(Collections.<String, String>emptyMap());
    }

    @Test(expected = IllegalStateException.class)
    public void testShouldDisplayWithBlankContext() throws Exception {
        condition.shouldDisplay(Collections.EMPTY_MAP);
    }

    @Test
    public void testShouldDisplay() throws Exception {

        when(likedComment.getId()).thenReturn(TOUCHED_COMMENT_ID);
        when(likedComment.getAuthor()).thenReturn(stashUser);
        when(defaultCommentLikeService.hasLike(repository, likedComment)).thenReturn(true);

        ImmutableMap<String, Object> context = ImmutableMap.<String, Object>builder()
                .putAll(buildContext(likedComment))
                .put("pullRequest", pullRequest).build();
        assertTrue("Wrong, user has liked this comment, so shouldDisplay() should return true",
                condition.shouldDisplay(context));
    }

    @Test
    public void testShouldNotDisplay() throws Exception {

        ApplicationUser mysteryUser = new TestApplicationUser("MysteryUser", 43434);

        when(notLikedComment.getId()).thenReturn(UNTOUCHED_COMMENT_ID);
        when(notLikedComment.getAuthor()).thenReturn(mysteryUser);
        when(defaultCommentLikeService.hasLike(repository, likedComment)).thenReturn(false);

        ImmutableMap<String, Object> context = ImmutableMap.<String, Object>builder()
                .putAll(buildContext(notLikedComment))
                .put("pullRequest", pullRequest).build();

        assertFalse("Wrong, User has not liked comment, so shouldDisplay() should return false",
                condition.shouldDisplay(context));
    }

}