package com.atlassian.bitbucket.mesh.git.mailmap;

import com.atlassian.bitbucket.mesh.AbstractWiredTest;
import com.atlassian.bitbucket.mesh.git.builder.GitProcessBuilderFactory;
import com.atlassian.bitbucket.mesh.io.MoreFiles;
import com.atlassian.bitbucket.mesh.junit.TemporaryDirectory;
import com.atlassian.bitbucket.mesh.process.handler.LoggingStdioHandler;
import com.atlassian.bitbucket.mesh.process.handler.StringStdioHandler;
import com.atlassian.bitbucket.mesh.repository.Repository;
import com.atlassian.bitbucket.mesh.test.annotation.DirtiesRepo;
import com.atlassian.bitbucket.mesh.test.annotation.Repo;
import com.atlassian.bitbucket.mesh.util.Person;
import org.junit.Rule;
import org.junit.Test;

import javax.annotation.Resource;
import java.io.IOException;
import java.nio.file.Path;

public class DefaultGitMailmapResolverTest extends AbstractWiredTest {

    private static final String MAPPED_EMAIL = "mapped@atlassian.com";
    private static final String MAPPED_USERNAME = "Mister Mapped";
    private static final String UNMAPPED_EMAIL = "mheemskerk@atlassian.com";
    private static final String UNMAPPED_USERNAME = "Who dis new phone?";

    @Rule
    public final TemporaryDirectory tempDir = new TemporaryDirectory();

    @Resource
    private GitProcessBuilderFactory builderFactory;
    @Repo
    private Repository repository;

    @DirtiesRepo
    @Test(timeout = 10000L)
    public void testResolve() throws Exception {
        createMailmap();

        try (DefaultGitMailmapResolver resolver = new DefaultGitMailmapResolver(builderFactory.builder(repository))) {
            // verify that the mailmap is used map the unmapped user
            Person resolved = resolver.resolve(new Person(UNMAPPED_USERNAME, UNMAPPED_EMAIL));
            assertNotNull(resolved);
            assertEquals(MAPPED_EMAIL, resolved.getEmail());
            assertEquals(MAPPED_USERNAME, resolved.getName());

            // verify that non-mapped users are left alone
            resolved = resolver.resolve(new Person("Bryan Turner", "bturner@atlassian.com"));
            assertNotNull(resolved);
            assertEquals("bturner@atlassian.com", resolved.getEmail());
            assertEquals("Bryan Turner", resolved.getName());
        }
    }

    private void createMailmap() throws IOException {
        Path repositoryDir = repository.getPath();
        Path cloneDir = tempDir.getRoot().resolve("mailmap-test");

        //Clone the repository so we can add a .mailmap file to it
        builderFactory.builder().clone().normal()
                .directory(cloneDir)
                .origin(repositoryDir)
                .workDir(tempDir.getRoot())
                .build(new LoggingStdioHandler())
                .run();

        //Write a the .mailmap file
        MoreFiles.write(cloneDir.resolve(".mailmap"),
                MAPPED_USERNAME + " <" + MAPPED_EMAIL + "> <" + UNMAPPED_EMAIL + ">");

        builderFactory.builder().add()
                .path(".mailmap")
                .workDir(cloneDir)
                .build(new LoggingStdioHandler())
                .run();

        //Commit the mailmap file
        builderFactory.builder().commit()
                .author(new Person("New phone who dis?", "mheemskerk@atlassian.com"))
                .message("Added a mailmap file")
                .workDir(cloneDir)
                .build(new StringStdioHandler())
                .run();

        //Disable the central git hooks on repository to allow the push to complete
        builderFactory.builder(repository).config().set("core.hooksPath", "dont-run").build().run();

        //Push up the commit to master
        builderFactory.builder().command("push").argument("origin").argument("master")
                .workDir(cloneDir)
                .build(new StringStdioHandler())
                .run();
    }
}