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

import com.atlassian.bitbucket.mesh.git.builder.GitProcess;
import com.atlassian.bitbucket.mesh.git.builder.GitProcessBuilder;
import com.atlassian.bitbucket.mesh.process.ProcessStdioHandler;
import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;

import javax.annotation.Nonnull;
import java.nio.file.Path;
import java.util.List;

public class DefaultGitNotesAddBuilder
        extends AbstractGitNotesBuilder<GitNotesAddBuilder>
        implements GitNotesAddBuilder {

    private final List<String> messages;

    private String file;
    private boolean force;

    public DefaultGitNotesAddBuilder(@Nonnull GitProcessBuilder builder, @Nonnull String object) {
        super(builder, object, "add");

        messages = Lists.newArrayList();
    }

    @Nonnull
    @Override
    public GitProcess<Void> build() {
        validateNoteIsSpecified();

        return buildWithLoggingHandler();
    }

    @Nonnull
    @Override
    public <T> GitProcess<T> build(@Nonnull ProcessStdioHandler<T> outputHandler) {
        validateNoteIsSpecified();

        return super.build(outputHandler);
    }

    @Nonnull
    @Override
    public GitNotesAddBuilder file(Path value) {
        file = value == null ? null : value.toAbsolutePath().toString();

        return self();
    }

    @Nonnull
    @Override
    public GitNotesAddBuilder force(boolean value) {
        force = value;

        return self();
    }

    @Nonnull
    @Override
    public GitNotesAddBuilder message(String value) {
        addIfNotBlank(messages, value);

        return self();
    }

    @Nonnull
    @Override
    public GitNotesAddBuilder messages(Iterable<String> values) {
        addIfNotBlank(messages, values);

        return self();
    }

    @Nonnull
    @Override
    public GitNotesAddBuilder messages(String value, String... values) {
        addIfNotBlank(messages, value, values);

        return self();
    }

    @Override
    protected void applyOptions() {
        if (force) {
            builder.argument("-f");
        }
        if (file != null) {
            builder.argument("-F")
                    .argument(file);
        }
        for (String message : messages) {
            builder.argument("-m")
                    .argument(message);
        }
    }

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

    private void validateNoteIsSpecified() {
        if (StringUtils.isBlank(file) && messages.isEmpty()) {
            throw new IllegalStateException("A file or a message must be specified when adding a note");
        }
    }
}
