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

import com.atlassian.bitbucket.mesh.git.builder.GitProcess;
import com.atlassian.bitbucket.mesh.git.builder.GitProcessBuilder;
import com.atlassian.bitbucket.mesh.git.builder.diff.GitDiffOutput;
import com.atlassian.bitbucket.mesh.git.builder.revlist.AbstractGitRevCoreBuilder;
import com.atlassian.bitbucket.mesh.git.exception.UnsupportedArgumentException;
import com.atlassian.bitbucket.mesh.process.ProcessStdioHandler;

import javax.annotation.Nonnull;

import static com.atlassian.bitbucket.mesh.rpc.v1.RpcUnsupportedArgument.Reason.UNSUPPORTED_COMBINATION;
import static java.util.Objects.requireNonNull;

public class DefaultGitLogBuilder extends AbstractGitRevCoreBuilder<GitLogBuilder> implements GitLogBuilder {

    private boolean follow;
    private GitDiffOutput output;

    public DefaultGitLogBuilder(GitProcessBuilder builder) {
        super(builder.command("log"));

        output = GitDiffOutput.DEFAULT;
    }

    @Nonnull
    @Override
    public <T> GitProcess<T> build(@Nonnull ProcessStdioHandler<T> stdioHandler) {
        GitProcess<T> process = super.build(stdioHandler);
        if (follow && skip > 0) {
            //We need the (full) command line to throw the UnsupportedArgumentException, which is why the check
            //is done here instead of in applyFlags.
            throw new UnsupportedArgumentException(UNSUPPORTED_COMBINATION,
                    "Setting --skip and --follow at the same time is not supported", process.toString());
        }
        return process;
    }

    @Nonnull
    @Override
    public GitLogBuilder follow(boolean value) {
        follow = value;

        return self();
    }

    @Nonnull
    @Override
    public GitLogBuilder output(@Nonnull GitDiffOutput value) {
        output = requireNonNull(value, "output");

        return self();
    }

    @Override
    protected void applyFlags() {
        super.applyFlags();

        if (follow) {
            builder.argument("--follow");
        }
        if (output.isFlagged()) {
            builder.argument(output.getFlag());
        }
    }

    @Override
    protected void applyRevs() {
        revs.forEach(builder::commitish);
    }

    @Nonnull
    @Override
    protected GitLogBuilder self() {
        return this;
    }
}
