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

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.tag.GitTagCreateBuilder;
import com.atlassian.bitbucket.scm.git.command.tag.GitTagType;
import org.apache.commons.lang3.StringUtils;

import javax.annotation.Nonnull;

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

/**
 * @since 3.6
 */
public class DefaultGitTagCreateBuilder
        extends AbstractGitCommandBuilder<GitTagCreateBuilder>
        implements GitTagCreateBuilder {

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

    private boolean force;
    private String message;
    private String startPoint;
    private GitTagType type;
    private boolean useDefaultExitHandler;

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

        this.i18nService = i18nService;
        this.name = checkNotBlank(name, "name");
        this.repository = repository;
        this.type = GitTagType.ANNOTATED;
        this.useDefaultExitHandler = true;
    }

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

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

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

        return self();
    }

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

        useDefaultExitHandler = false;

        return self();
    }
    
    @Nonnull
    @Override
    public GitTagCreateBuilder force(boolean value) {
        force = value;

        return self();
    }

    @Nonnull
    @Override
    public GitTagCreateBuilder message(String value) {
        message = value;

        return self();
    }

    @Nonnull
    @Override
    public GitTagCreateBuilder startPoint(@Nonnull String value) {
        startPoint = checkNotNull(value, "startPoint");

        return self();
    }

    @Nonnull
    @Override
    public GitTagCreateBuilder type(@Nonnull GitTagType value) {
        type = checkNotNull(value, "type");

        return self();
    }

    @Override
    protected void applyArguments() {
        if (GitTagType.ANNOTATED.equals(type)) {
            builder.argument("-a");
            builder.argument("-m");
            builder.argument(StringUtils.isNotBlank(message) ? message : i18nService.getMessage("bitbucket.git.tag.defaultmessage", startPoint));
        }
        if (force) {
            builder.argument("-f");
        }
        builder.argument(name);
        if (StringUtils.isNotBlank(startPoint)) {
            builder.argument(startPoint);
        }
    }

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