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

import com.atlassian.bitbucket.mesh.git.builder.AbstractGitProcessBuilder;
import com.atlassian.bitbucket.mesh.git.builder.GitProcessBuilder;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.nio.file.Path;
import java.time.Duration;

import static com.google.common.base.Preconditions.checkState;
import static java.util.Objects.requireNonNull;

public class DefaultGitUploadPackBuilder
        extends AbstractGitProcessBuilder<GitUploadPackBuilder>
        implements GitUploadPackBuilder {

    private boolean advertiseRefs;
    private Path directory;
    private boolean statelessRpc;
    private boolean strict;
    private Duration timeout;

    public DefaultGitUploadPackBuilder(GitProcessBuilder builder, Path directory) {
        super(builder.command("upload-pack"));

        //Default to the repository's directory, if one was set, so callers don't need to redundantly
        //pass it to directory(Path)
        this.directory = directory;
    }

    @Nonnull
    @Override
    public GitUploadPackBuilder advertiseRefs(boolean value) {
        advertiseRefs = value;

        return self();
    }

    @Nonnull
    @Override
    public GitUploadPackBuilder directory(@Nonnull Path value) {
        directory = requireNonNull(value, "directory");

        return self();
    }

    @Nonnull
    @Override
    public GitUploadPackBuilder statelessRpc(boolean value) {
        statelessRpc = value;

        return self();
    }

    @Nonnull
    @Override
    public GitUploadPackBuilder strict(boolean value) {
        strict = value;

        return self();
    }

    @Nonnull
    @Override
    public GitUploadPackBuilder timeout(@Nullable Duration value) {
        timeout = value;

        return self();
    }

    @Override
    protected void applyArguments() {
        checkState(directory != null, "git upload-pack requires a path");

        if (advertiseRefs) {
            builder.argument("--advertise-refs");
        }
        if (statelessRpc) {
            builder.argument("--stateless-rpc");
        }
        if (strict) {
            builder.argument("--strict");
        }
        if (timeout != null) {
            builder.argument("--timeout=" + timeout.getSeconds());
        }
        builder.rawArgument(directory.toString());
    }

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