package com.atlassian.stash.internal.pull.comment;

import com.atlassian.stash.internal.comment.InternalComment;
import com.atlassian.stash.internal.comment.InternalCommentable;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

import java.util.Set;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertSame;
import static org.mockito.Matchers.eq;
import static org.mockito.Matchers.same;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

@RunWith(MockitoJUnitRunner.class)
public class CompositeCommentPostProcessorTest {

    @Mock
    private CommentPostProcessor processor1;
    @Mock
    private CommentPostProcessor processor2;
    @Mock
    private CommentPostProcessor processor3;

    private CompositeCommentPostProcessor composite;

    @Before
    public void setUp() throws Exception {
        composite = new CompositeCommentPostProcessor(ImmutableList.of(processor1, processor2), processor3);
    }

    @Test
    public void testProcess() throws Exception {
        InternalCommentable commentable = mock(InternalCommentable.class);
        InternalComment comment1 = mock(InternalComment.class);
        InternalComment comment2 = mock(InternalComment.class);
        InternalComment comment3 = mock(InternalComment.class);
        InternalComment comment4 = mock(InternalComment.class);
        when(processor1.process(same(commentable), same(comment1))).thenReturn(comment2);
        when(processor2.process(same(commentable), same(comment2))).thenReturn(comment3);
        when(processor3.process(same(commentable), same(comment3))).thenReturn(comment4);

        InternalComment comment = composite.process(commentable, comment1);
        assertSame(comment4, comment);
    }

    @Test
    public void testProcessAll() throws Exception {
        InternalCommentable commentable = mock(InternalCommentable.class);
        InternalComment comment1 = mock(InternalComment.class);
        InternalComment comment2 = mock(InternalComment.class);
        InternalComment comment3 = mock(InternalComment.class);
        InternalComment comment4 = mock(InternalComment.class);
        when(processor1.processAll(same(commentable), eq(ImmutableSet.of(comment1)))).thenReturn(ImmutableSet.of(comment2));
        when(processor2.processAll(same(commentable), eq(ImmutableSet.of(comment2)))).thenReturn(ImmutableSet.of(comment3));
        when(processor3.processAll(same(commentable), eq(ImmutableSet.of(comment3)))).thenReturn(ImmutableSet.of(comment4));

        Set<InternalComment> comments = composite.processAll(commentable, ImmutableSet.of(comment1));
        assertEquals(ImmutableSet.of(comment4), comments);
    }

}