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

import com.atlassian.bitbucket.mesh.git.builder.GitProcessBuilderSupport;

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

/**
 * A builder for {@code git upload-pack} commands. {@code git upload-pack} takes minimal command line
 * parameters (essentially just a repository directory), so this builder is also minimal.
 */
public interface GitUploadPackBuilder extends GitProcessBuilderSupport<GitUploadPackBuilder> {

    /**
     * Instructs {@code upload-pack} to advertise refs and then terminate, rather than waiting for a request. This
     * allows {@code upload-pack} to be used to implement HTTP handling, where refs are advertised in one request
     * and then a pack is downloaded in a second request.
     *
     * @param value {@code true} to only advertise refs; otherwise {@code false} to also upload a pack
     * @return {@code this}
     */
    @Nonnull
    GitUploadPackBuilder advertiseRefs(boolean value);

    @Nonnull
    GitUploadPackBuilder directory(@Nonnull Path value);

    /**
     * Limits {@code upload-pack} to a single cycle reading from {@code stdin} and writing to {@code stdout}. This
     * allows {@code upload-pack} to be used to implement HTTP handling instead of {@code http-backend}. The default
     * allows multiple cycles, which is useful for implementing SSH handling.
     *
     * @param value {@code true} to apply a single cycle; otherwise, {@code false} to allow multiple cycles
     * @return {@code this}
     */
    @Nonnull
    GitUploadPackBuilder statelessRpc(boolean value);

    /**
     * Controls whether {@code upload-pack} allows non-bare repositories.
     *
     * @param value {@code true} to require a bare repository; {@code false} to allow bare or non-bare repositories
     * @return {@code this}
     */
    @Nonnull
    GitUploadPackBuilder strict(boolean value);

    /**
     * Instructs {@code upload-pack} to automatically terminate if idle for a specified duration. This allows
     * Git to terminate processing on its own, rather than relying on a process-level timeout killing it.
     *
     * @param value the timeout, or {@code null} to not apply one (note that a process-level timeout may still
     *              be applied even if no {@code upload-pack} timeout is configured here)
     * @return {@code this}
     */
    @Nonnull
    GitUploadPackBuilder timeout(@Nullable Duration value);
}