package com.atlassian.bitbucket.mesh.git.builder.countobjects;

import com.atlassian.bitbucket.mesh.repository.RepositorySize;
import org.junit.Test;

import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;

public class RepositorySizeCountObjectsStdioHandlerTest {

    @Test
    public void testNoCommandOutput() {
        RepositorySize repositorySize = parseOutput("");

        assertThat(repositorySize.getGarbageSize(), is(0L));
        assertThat(repositorySize.getInPackSize(), is(0L));
        assertThat(repositorySize.getLooseSize(), is(0L));
    }

    @Test
    public void testOutputWithAllSizeValuesPresent() {
        String commandOutput = "count: 3\n" +
                               "size: 10\n" +
                               "in-pack: 2482\n" +
                               "packs: 24\n" +
                               "size-pack: 1000\n" +
                               "prune-packable: 45\n" +
                               "garbage: 1\n" +
                               "size-garbage: 100";
        RepositorySize repositorySize = parseOutput(commandOutput);

        assertThat(repositorySize.getGarbageSize(), is(100L));
        assertThat(repositorySize.getInPackSize(), is(1000L));
        assertThat(repositorySize.getLooseSize(), is(10L));
    }

    @Test
    public void testOutputForForkedRepository() {
        String commandOutput = "count: 3\n" +
                               "size: 10\n" +
                               "in-pack: 2482\n" +
                               "packs: 24\n" +
                               "size-pack: 1000\n" +
                               "prune-packable: 45\n" +
                               "garbage: 1\n" +
                               "size-garbage: 100\n" +
                               "alternate: /var/bitbucket-home/shared/data/repositories/125/objects";
        RepositorySize repositorySize = parseOutput(commandOutput);

        assertThat(repositorySize.getGarbageSize(), is(100L));
        assertThat(repositorySize.getInPackSize(), is(1000L));
        assertThat(repositorySize.getLooseSize(), is(10L));
    }

    @Test
    public void testMissingOutputForSomeFields() {
        String commandOutput = "count: 3\n" +
                               "in-pack: 2482\n" +
                               "prune-packable: 45\n" +
                               "garbage: 1\n" +
                               "size-garbage: 100\n";
        RepositorySize repositorySize = parseOutput(commandOutput);

        assertThat(repositorySize.getGarbageSize(), is(100L));
        assertThat(repositorySize.getInPackSize(), is(0L));
        assertThat(repositorySize.getLooseSize(), is(0L));
    }

    @Test
    public void testOutputWithInvalidLines() {
        String commandOutput = "count: 3\n" +
                               "size: 10\n" +
                               "in-pack: 2482\n" +
                               "packs: 24\n" +
                               "size-pack\n" +
                               "some junk value - 10\n" +
                               "prune-packable: 45\n" +
                               "garbage: 1\n" +
                               "size-garbage: 100";
        RepositorySize repositorySize = parseOutput(commandOutput);

        assertThat(repositorySize.getGarbageSize(), is(100L));
        assertThat(repositorySize.getInPackSize(), is(0L));
        assertThat(repositorySize.getLooseSize(), is(10L));
    }

    private static RepositorySize parseOutput(String output) {
        RepositorySizeCountObjectsStdioHandler handler = new RepositorySizeCountObjectsStdioHandler();
        handler.onStdout(ByteBuffer.wrap(output.getBytes(StandardCharsets.UTF_8)), true);

        return handler.getResult();
    }
}