package com.atlassian.stash.internal.scm.git.command.foreachref;

import com.atlassian.bitbucket.repository.Branch;
import com.atlassian.bitbucket.repository.Ref;
import com.atlassian.bitbucket.repository.RefCallback;
import com.atlassian.bitbucket.repository.Tag;
import com.atlassian.bitbucket.scm.CommandResult;
import com.atlassian.bitbucket.scm.CommandSummary;
import com.atlassian.bitbucket.scm.git.GitRefPattern;
import com.atlassian.utils.process.Watchdog;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.springframework.core.io.ClassPathResource;

import java.util.List;

import static org.junit.Assert.*;
import static org.mockito.Mockito.*;

public class HeadsForEachRefOutputHandlerTest {

    @Test
    public void testExecute() throws Exception {
        RefCallback callback = mock(RefCallback.class);
        when(callback.onRef(any(Ref.class))).thenReturn(true);

        HeadsForEachRefOutputHandler handler = new HeadsForEachRefOutputHandler(callback, "refs/heads/master");
        handler.setWatchdog(mock(Watchdog.class));
        handler.process(new ClassPathResource("git-for-each-ref-heads.out", getClass()).getInputStream());
        handler.onComplete(new CommandSummary.Builder(CommandResult.SUCCEEDED).build());

        ArgumentCaptor<Ref> refCaptor = ArgumentCaptor.forClass(Ref.class);
        verify(callback, times(7)).onRef(refCaptor.capture());

        List<Ref> refs = refCaptor.getAllValues();
        assertBranch("CAV-1121-indexing-framework", "883ed39388fb4cad5bfbb13655886d9668bfcae9", false, refs.get(0));
        assertBranch("CAV-1274-db-rename", "26f5acce1665623a8f1ea868b21d004555e802ba", false, refs.get(1));
        assertBranch("CAV-288-push-event", "2d58ad090fcc505589d02533b105fa4dd7847f27", false, refs.get(2));
        assertBranch("CAV-962-id-generation-not-working", "721c641e6dd720177022d657a9f3b8f7435e9c22", false, refs.get(3));
        assertBranch("master", "8b61f285a48e7fdea2ea7981030283834dd62117", true, refs.get(4));
        assertTag("atlassian-stash-parent-1.0-m0", "d11c81cead00711b017dad8950d7011da3b0b815", "cbce4e2eacb6156fef4b22d0e949d54f3286c31b", refs.get(5));
        assertTag("b", "0a943a29376f2336b78312d99e65da17048951db", refs.get(6));
    }

    private static void assertBranch(String name, String latestCommit, boolean defaultBranch, Ref ref) {
        assertTrue(ref instanceof Branch);
        Branch branch = (Branch) ref;

        assertEquals(GitRefPattern.HEADS.qualify(name), ref.getId());
        assertEquals(name, branch.getDisplayId());
        assertEquals(latestCommit, branch.getLatestCommit());
        assertEquals(defaultBranch, branch.getIsDefault());
    }

    private static void assertTag(String name, String latestCommit, Ref ref) {
        assertTag(name, null, latestCommit, ref);
    }

    private static void assertTag(String name, String hash, String latestCommit, Ref ref) {
        assertTrue(ref instanceof Tag);
        Tag tag = (Tag) ref;

        assertEquals(GitRefPattern.TAGS.qualify(name), ref.getId());
        assertEquals(name, tag.getDisplayId());
        if (hash == null) {
            assertNull(tag.getHash());
        } else {
            assertEquals(hash, tag.getHash());
        }
        assertEquals(latestCommit, tag.getLatestCommit());
    }
}
