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

import com.atlassian.bitbucket.repository.Repository;
import com.atlassian.bitbucket.scm.annotation.DirtiesRepo;
import com.atlassian.bitbucket.scm.annotation.Repo;
import com.atlassian.bitbucket.scm.git.GitScmConfig;
import com.atlassian.bitbucket.scm.git.command.GitCommandBuilderFactory;
import com.atlassian.stash.internal.scm.git.AbstractGitTest;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;

import java.io.File;

public class PackLooseObjectsCommandTest extends AbstractGitTest {

    @Autowired
    private GitCommandBuilderFactory builderFactory;
    @Autowired
    private GitScmConfig config;
    @Repo("classpath:git/garbage.zip")
    private Repository repository;

    @DirtiesRepo
    @Test
    public void testCall() {
        File objectsDir = config.getObjectsDir(repository);

        //Verify that the repository has loose objects. If it doesn't, this test can't verify anything
        String[] prefixes = objectsDir.list(PackLooseObjectsCommand.FILTER_PREFIX);
        assertTrue("The repository has no loose objects", prefixes != null && prefixes.length > 0);

        //Pack all of the loose objects in the repository
        String packId = new PackLooseObjectsCommand(builderFactory, config, repository).call();
        assertNotNull("The ID of the generated pack should have been returned", packId);

        //Verify that the pack exists and has no .keep file
        File pack = PackLooseObjectsCommand.format(objectsDir, packId, PackLooseObjectsCommand.PACK);
        File keep = PackLooseObjectsCommand.format(objectsDir, packId, PackLooseObjectsCommand.KEEP);
        assertTrue("The pack should exist on disk", pack.isFile());
        assertFalse("The pack should not be protected by a .keep file", keep.isFile());

        //Verify that the repository no longer contains any loose objects
        prefixes = objectsDir.list(PackLooseObjectsCommand.FILTER_PREFIX);
        assertTrue("All loose objects should have been packed", prefixes != null && prefixes.length == 0);

        //Run normal garbage collection (not auto). This verifies that the "dead" pack is unpacked and
        //removed. This prevents creating multiple "dead" packs and instead re-consolidates all of the
        //"dead" objects each time garbage collection is run
        builderFactory.builder(repository).gc().build().call();
        assertFalse("git gc should have removed the pack", pack.isFile());

        //Verify that the repository again contains loose objects
        prefixes = objectsDir.list(PackLooseObjectsCommand.FILTER_PREFIX);
        assertTrue("Unreachable objects should not have been unpacked", prefixes != null && prefixes.length > 0);
    }
}
