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

import com.atlassian.bitbucket.commit.Commit;
import com.atlassian.bitbucket.commit.MinimalCommit;
import com.atlassian.bitbucket.context.DelegatingTestExecutionListener;
import com.atlassian.bitbucket.repository.Repository;
import com.atlassian.bitbucket.scm.annotation.Repo;
import com.atlassian.bitbucket.user.ApplicationUser;
import com.atlassian.bitbucket.user.Person;
import org.junit.Assert;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import java.util.Collection;
import java.util.Date;

/**
 * Base class for building tests which rely on executing {@code git} against a repository. Tests derived from this
 * base class may declare {@code private} fields of {@link Repository} type and annotate them with {@link Repo} to
 * have a repository automatically extracted, prepared by the test framework and injected for use.
 */
@ContextConfiguration(locations = "classpath:git-spring.xml")
@RunWith(SpringJUnit4ClassRunner.class)
@TestExecutionListeners(DelegatingTestExecutionListener.class)
public abstract class AbstractGitTest extends Assert {

    protected static void assertAuthor(ApplicationUser expected, Person actual) {
        assertNotNull(actual);
        assertEquals(expected.getDisplayName(), actual.getName());
        assertEquals(expected.getEmailAddress(), actual.getEmailAddress());
    }

    protected static void assertCommit(Commit commit, String authorName, String authorEmail, Date authorTimestamp,
                                       String displayId, String id, String message,
                                       String parentDisplayId, String parentId) {
        assertCommit(commit, authorName, authorEmail, authorTimestamp, displayId, id, message);

        Collection<MinimalCommit> parents = commit.getParents();
        assertNotNull(parents);
        assertEquals(1, parents.size());

        MinimalCommit parent = parents.iterator().next();
        assertEquals(parentDisplayId, parent.getDisplayId());
        assertEquals(parentId, parent.getId());
    }

    protected static void assertCommit(Commit commit, String authorName, String authorEmail, Date authorTimestamp,
                                       String displayId, String id, String message) {
        assertEquals(authorName, commit.getAuthor().getName());
        assertEquals(authorEmail, commit.getAuthor().getEmailAddress());
        assertEquals(authorTimestamp, commit.getAuthorTimestamp());
        assertEquals(displayId, commit.getDisplayId());
        assertEquals(id, commit.getId());
        assertEquals(message, commit.getMessage());
    }
}
