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

import com.atlassian.bitbucket.mesh.process.handler.AbstractLineStdioHandler;
import com.atlassian.bitbucket.mesh.repository.RepositorySize;
import com.google.common.collect.ImmutableMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.Nonnull;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.function.BiConsumer;
import java.util.regex.Pattern;

public class RepositorySizeCountObjectsStdioHandler extends AbstractLineStdioHandler<RepositorySize> {

    private static final Logger log = LoggerFactory.getLogger(RepositorySizeCountObjectsStdioHandler.class);

    private static final Pattern DELIMITER = Pattern.compile(":\\s+");
    private static final Map<String, BiConsumer<RepositorySize.Builder, Long>> FIELDS =
            ImmutableMap.<String, BiConsumer<RepositorySize.Builder, Long>>builder()
                    .put("size", RepositorySize.Builder::looseSize)
                    .put("size-pack", RepositorySize.Builder::inPackSize)
                    .put("size-garbage", RepositorySize.Builder::garbageSize)
                    .build();

    private final RepositorySize.Builder builder;

    public RepositorySizeCountObjectsStdioHandler() {
        super(StandardCharsets.UTF_8);

        builder = new RepositorySize.Builder();
    }

    @Nonnull
    @Override
    public RepositorySize getResult() {
        return builder.build();
    }

    @Override
    protected boolean onStdout(@Nonnull String line, boolean truncated) {
        String[] fields = DELIMITER.split(line, 2);
        if (fields.length != 2) {
            log.debug("Could not parse line: {}", line);
            return true;
        }
        String field = fields[0];
        BiConsumer<RepositorySize.Builder, Long> adapter = FIELDS.get(field);
        if (adapter != null) {
            long value = Long.parseLong(fields[1]);
            adapter.accept(builder, value);
        }
        return true;
    }
}
