package com.atlassian.bitbucket.internal.branch.list.aheadbehind;

import com.atlassian.bitbucket.commit.CommitService;
import com.atlassian.bitbucket.commit.graph.TraversalCallback;
import com.atlassian.bitbucket.commit.graph.TraversalRequest;
import com.atlassian.bitbucket.repository.Ref;
import com.atlassian.bitbucket.repository.RefMetadataContext;
import com.google.common.collect.ImmutableSet;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

import java.util.Map;

import static com.atlassian.bitbucket.internal.branch.MetadataProviderTestUtils.mockContext;
import static com.atlassian.bitbucket.internal.branch.MetadataProviderTestUtils.mockRef;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertSame;
import static org.mockito.Matchers.notNull;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;

@RunWith(MockitoJUnitRunner.class)
public class AheadBehindRefMetadataProviderTest {

    @Mock
    private CommitService commitService;
    @InjectMocks
    private AheadBehindRefMetadataProvider metadataProvider;

    @Test
    public void testShouldSkipServiceInteractionsWhenPassedNoRefs() {
        Ref baseRef = mockRef("master");
        RefMetadataContext context = mockContext(baseRef, ImmutableSet.<Ref>of());
        Map<Ref, AheadBehindCount> result = metadataProvider.getMetadata(context);
        assertEquals(0, result.size());
        verifyZeroInteractions(commitService);
    }

    @Test
    public void testShouldIgnoreComparisonWithSelf() {
        Ref baseRef = mockRef("master");
        RefMetadataContext context = mockContext(baseRef, ImmutableSet.of(baseRef));
        Map<Ref, AheadBehindCount> result = metadataProvider.getMetadata(context);
        assertEquals(0, result.size());
    }

    @Test
    public void testShouldCallTraverseOnCommitServiceWithCorrectCommitIds() {
        Ref baseRef = mockRef("master");
        Ref otherRef = mockRef("foo");
        RefMetadataContext context = mockContext(baseRef, ImmutableSet.of(otherRef));
        metadataProvider.getMetadata(context);

        ArgumentCaptor<TraversalRequest> request = ArgumentCaptor.forClass(TraversalRequest.class);
        verify(commitService).traverse(request.capture(), notNull(TraversalCallback.class));
        assertSame(context.getRepository(), request.getValue().getRepository());
        assertEquals(ImmutableSet.of("commit-id-foo", "commit-id-master"), request.getValue().getIncludes());
        assertEquals(ImmutableSet.<String>of(), request.getValue().getExcludes());
    }

}
