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

import com.atlassian.bitbucket.mesh.git.ref.Branch;
import com.atlassian.bitbucket.mesh.git.ref.Ref;
import com.atlassian.bitbucket.mesh.git.ref.Tag;
import com.atlassian.bitbucket.mesh.process.handler.AbstractLineStdioHandler;
import com.atlassian.bitbucket.mesh.util.SatiableConsumer;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.nio.charset.StandardCharsets;

import static com.atlassian.bitbucket.mesh.git.GitRefPattern.TAGS;

public class AllRefsForEachRefStdioHandler extends AbstractLineStdioHandler<Void> implements ForEachRefStdioHandler<Void> {

    public static final String FORMAT = ForEachRefUtils.normalize("%(refname)|%(objectname)|%(*objectname)");

    private final SatiableConsumer<Ref> callback;
    private final String defaultBranch;

    public AllRefsForEachRefStdioHandler(SatiableConsumer<Ref> callback, String defaultBranch) {
        super(StandardCharsets.UTF_8);

        this.callback = callback;
        this.defaultBranch = defaultBranch;
    }

    @Nonnull
    @Override
    public String getFormat() {
        return FORMAT;
    }

    @Nullable
    @Override
    public Void getResult() {
        return null;
    }

    @Override
    protected boolean onStdout(@Nonnull String line, boolean truncated) {
        String[] pieces = line.split(ForEachRefUtils.SEPARATOR_CHAR);
        if (pieces.length < 2) {
            return true;
        }

        Ref ref;
        if (pieces[0].startsWith(TAGS.getPath())) {
            Tag.Builder builder = new Tag.Builder()
                    .id(pieces[0]);
            if (pieces.length == 3) {
                //Annotated tag
                builder.hash(pieces[1]).latestCommit(pieces[2]).build();
            } else {
                //Lightweight tag
                builder.latestCommit(pieces[1]).build();
            }
            ref = builder.build();
        } else {
            ref = new Branch.Builder()
                    .id(pieces[0])
                    .isDefault(defaultBranch.equals(pieces[0]))
                    .latestCommit(pieces[1])
                    .build();
        }

        return !callback.accept(ref);
    }
}
