package com.atlassian.stash.internal.scm.git.command.branch;

import com.atlassian.bitbucket.i18n.I18nService;
import com.atlassian.stash.internal.scm.git.command.AbstractGitCommandBuilder;
import com.atlassian.bitbucket.repository.Repository;
import com.atlassian.bitbucket.scm.Command;
import com.atlassian.bitbucket.scm.CommandExitHandler;
import com.atlassian.bitbucket.scm.CommandOutputHandler;
import com.atlassian.bitbucket.scm.git.command.GitCommand;
import com.atlassian.bitbucket.scm.git.command.GitScmCommandBuilder;
import com.atlassian.bitbucket.scm.git.command.branch.GitBranchCreateBuilder;
import org.apache.commons.lang3.StringUtils;

import javax.annotation.Nonnull;

import static com.google.common.base.Preconditions.checkArgument;

public class DefaultGitBranchCreateBuilder
        extends AbstractGitCommandBuilder<GitBranchCreateBuilder>
        implements GitBranchCreateBuilder {

    private final String name;
    private final I18nService i18nService;
    private final Repository repository;

    private boolean force;
    private boolean reflog;
    private String startPoint;
    private boolean track;
    private boolean useDefaultExitHandler;

    public DefaultGitBranchCreateBuilder(GitScmCommandBuilder builder, I18nService i18nService,
                                         Repository repository, String name) {
        super(builder);

        checkArgument(StringUtils.isNotBlank(name), "A branch name is required");
        this.name = name;
        this.i18nService = i18nService;
        this.repository = repository;
        this.useDefaultExitHandler = true;
    }

    @Nonnull
    @Override
    public Command<Void> build() {
        if (useDefaultExitHandler) {
            builder.exitHandler(new CreateBranchCommandExitHandler(i18nService, repository));
        }
        return buildWithLoggingHandler();
    }

    @Nonnull
    @Override
    public <T> GitCommand<T> build(@Nonnull CommandOutputHandler<T> outputHandler) {
        if (useDefaultExitHandler) {
            builder.exitHandler(new CreateBranchCommandExitHandler(i18nService, repository));
        }
        return super.build(outputHandler);
    }

    @Nonnull
    @Override
    public GitBranchCreateBuilder defaultExitHandler() {
        useDefaultExitHandler = true;

        return self();
    }

    @Nonnull
    @Override
    public GitBranchCreateBuilder exitHandler(@Nonnull CommandExitHandler value) {
        super.exitHandler(value);

        useDefaultExitHandler = false;

        return self();
    }

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

        return self();
    }

    @Nonnull
    @Override
    public GitBranchCreateBuilder reflog(boolean value) {
        reflog = value;

        return self();
    }

    @Nonnull
    @Override
    public GitBranchCreateBuilder startPoint(@Nonnull String value) {
        startPoint = value;

        return self();
    }

    @Nonnull
    @Override
    public GitBranchCreateBuilder track(boolean value) {
        track = value;

        return self();
    }

    @Override
    protected void applyArguments() {
        if (force) {
            builder.argument("-f");
        }
        if (reflog) {
            builder.argument("-l");
        }
        if (track) {
            builder.argument("--track");
        } else {
            builder.argument("--no-track");
        }
        builder.argument(name);
        if (StringUtils.isNotBlank(startPoint)) {
            builder.argument(startPoint);
        }
    }

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