package com.atlassian.stash.internal.plugin.hooks.task;

import com.atlassian.bitbucket.i18n.I18nService;
import com.atlassian.bitbucket.pull.PullRequest;
import com.atlassian.bitbucket.pull.PullRequestRef;
import com.atlassian.bitbucket.pull.PullRequestService;
import com.atlassian.bitbucket.repository.Repository;
import com.atlassian.bitbucket.scm.pull.MergeRequest;
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 static com.atlassian.bitbucket.task.TaskMatchers.hasContext;
import static com.atlassian.bitbucket.task.TaskTestUtils.createTaskCount;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.*;

@RunWith(MockitoJUnitRunner.class)
public class IncompleteTasksMergeCheckTest {

    private static final int REPOSITORY_ID = 99;

    private static final long PULL_REQUEST_ID = 59;

    @Mock
    private PullRequest pullRequest;
    @Mock
    private Repository repository;
    @Mock
    private IncompleteTasksMergeCheckConfig pullRequestTaskConfig;
    @Mock
    private I18nService i18nService;
    @Mock
    private PullRequestService pullRequestService;
    @Mock
    private MergeRequest mergeCheck;

    @InjectMocks
    private IncompleteTasksMergeCheck pullRequestTaskResolvedMergeCheck;

    @Before
    public void setUp() throws Exception {
        PullRequestRef ref = mock(PullRequestRef.class);

        when(mergeCheck.getPullRequest()).thenReturn(pullRequest);
        when(pullRequest.getId()).thenReturn(PULL_REQUEST_ID);
        when(pullRequest.getToRef()).thenReturn(ref);
        when(ref.getRepository()).thenReturn(repository);
        when(repository.getId()).thenReturn(REPOSITORY_ID);
    }

    @Test
    public void testCheckShouldNotVetoIfAllTasksAreResolved() throws Exception {
        when(pullRequestTaskConfig.isResolutionRequired(repository)).thenReturn(true);
        when(pullRequestService.countTasks(argThat(hasContext(pullRequest)))).thenReturn(createTaskCount(0, 0));

        pullRequestTaskResolvedMergeCheck.check(mergeCheck);

        verify(mergeCheck, never()).veto(anyString(), anyString());
    }

    @Test
    public void testCheckShouldNotVetoIfRequireTasksResolvedIsFalse() throws Exception {
        when(pullRequestTaskConfig.isResolutionRequired(repository)).thenReturn(false);

        pullRequestTaskResolvedMergeCheck.check(mergeCheck);

        verify(mergeCheck, never()).veto(anyString(), anyString());
    }

    @Test
    public void testCheckShouldVetoIfAllTasksAreNotResolved() throws Exception {
        when(pullRequestTaskConfig.isResolutionRequired(repository)).thenReturn(true);
        when(pullRequestService.countTasks(argThat(hasContext(pullRequest)))).thenReturn(createTaskCount(1, 0));

        pullRequestTaskResolvedMergeCheck.check(mergeCheck);

        verify(mergeCheck).veto(anyString(), anyString());
    }

}