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

import com.atlassian.bitbucket.mesh.git.builder.AbstractGitProcessBuilder;
import com.atlassian.bitbucket.mesh.git.builder.GitProcessBuilder;
import com.atlassian.bitbucket.mesh.repository.Repository;
import org.apache.commons.lang3.StringUtils;

import javax.annotation.Nonnull;
import java.util.ArrayList;
import java.util.List;

public class DefaultGitPushBuilder extends AbstractGitProcessBuilder<GitPushBuilder> implements GitPushBuilder {

    private final List<String> refspecs;

    private boolean atomic;
    private boolean force;
    private boolean porcelain;
    private boolean progress;
    private boolean prune;
    private String repository;

    public DefaultGitPushBuilder(GitProcessBuilder builder) {
        super(builder.command("push"));

        refspecs = new ArrayList<>();
    }

    @Nonnull
    @Override
    public GitPushBuilder atomic(boolean value) {
        atomic = value;

        return self();
    }

    @Nonnull
    @Override
    public GitPushBuilder clearRefspecs() {
        refspecs.clear();

        return self();
    }

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

        return self();
    }

    @Nonnull
    @Override
    public GitPushBuilder porcelain(boolean value) {
        porcelain = value;

        return self();
    }

    @Nonnull
    @Override
    public GitPushBuilder progress(boolean value) {
        progress = value;

        return self();
    }

    @Nonnull
    @Override
    public GitPushBuilder prune(boolean value) {
        prune = value;

        return self();
    }

    @Nonnull
    @Override
    public GitPushBuilder refspec(String value) {
        addIfNotBlank(refspecs, value);

        return self();
    }

    @Nonnull
    @Override
    public GitPushBuilder refspecs(Iterable<String> values) {
        addIfNotBlank(refspecs, values);

        return self();
    }

    @Nonnull
    @Override
    public GitPushBuilder refspecs(String value, String... values) {
        addIfNotBlank(refspecs, value, values);

        return self();
    }

    @Nonnull
    @Override
    public GitPushBuilder repository(Repository value) {
        return repository(value == null ? null : value.getPath().toString());
    }

    @Nonnull
    @Override
    public GitPushBuilder repository(String value) {
        repository = value;

        return self();
    }

    @Override
    protected void applyArguments() {
        if (atomic) {
            builder.argument("--atomic");
        }
        if (prune) {
            builder.argument("--prune");
        }
        if (force) {
            builder.argument("--force"); //This can only end well...
        }
        if (progress) {
            builder.argument("--progress");
        }
        if (porcelain) {
            builder.argument("--porcelain");
        }
        if (StringUtils.isNotBlank(repository)) {
            builder.argument(repository);
            for (String refspec : refspecs) {
                builder.argument(refspec);
            }
        }
    }

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