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

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

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

/**
 * A type-safe builder for {@code git ls-tree}.
 */
public interface GitLsTreeBuilder extends GitProcessBuilderSupport<GitLsTreeBuilder> {

    /**
     * reset the paths provided to empty
     * @return {@code this}
     */
    @Nonnull
    GitLsTreeBuilder clearPaths();

    /**
     * @param value {@code true} to pass {@code -z} to {@code git ls-tree}; otherwise, {@code false}
     * @return {@code this}
     */
    @Nonnull
    GitLsTreeBuilder nullTerminated(boolean value);

    /**
     * Offers a way to filter the subtree passed in via {@link #tree(String, String)} to zero to many paths by
     * matching the name of the node in the tree. For example,
     * <pre><code>
     *     .tree("master", "src/main/java")
     *     .path("javafile.java")
     * </code></pre>
     * will ensure that from the <i>"src/main/java"</i> tree, only the file <i>"javafile.java"</i> is selected.
     * <p>
     * This is not exclusive to files, and the path can be for a file, directory, or submodule.
     *
     * @param path a node on the tree passed to {@link #tree(String, String)}
     * @return {@code this}
     */
    @Nonnull
    GitLsTreeBuilder path(@Nullable String path);

    /**
     * @param value value
     * @param values values
     * @return {@code this}
     * @see #path(String)
     */
    @Nonnull
    GitLsTreeBuilder paths(@Nullable String value, @Nullable String... values);

    /**
     * @param values path iterable
     * @return {@code this}
     * @see #path(String)
     */
    @Nonnull
    GitLsTreeBuilder paths(@Nullable Iterable<String> values);

    /**
     * @param value {@code true} to pass {@code -r} to {@code git ls-tree}; otherwise, {@code false}
     * @return {@code this}
     */
    @Nonnull
    GitLsTreeBuilder recursive(boolean value);

    /**
     * @param value {@code true} to pass {@code -l} to {@code git ls-tree}; otherwise, {@code false}
     * @return {@code this}
     */
    @Nonnull
    GitLsTreeBuilder sizes(boolean value);

    /**
     * @param value the {@code tree-ish} (typically a {@code commit} or {@code tree} by ref name or SHA-1)
     *              to pass to {@code git ls-tree}
     * @return {@code this}
     */
    @Nonnull
    GitLsTreeBuilder tree(@Nonnull String value);

    /**
     * Offers a convenient shorthand for identifying a subtree in a given commit. For example, passing
     * {@code ("master", "src/main/java")} will output the contents of the {@code src/main/java} tree
     * on the "master" branch. Note that passing "master:src/main/java" to {@link #tree(String)} would
     * produce the same output.
     *
     * @param rev  the commit to display the tree at, identified by ref name or SHA-1
     * @param file the path of the tree to display, which may be {@code ""} to display the root tree
     * @return {@code this}
     */
    @Nonnull
    GitLsTreeBuilder tree(@Nonnull String rev, @Nullable String file);
}
