package com.atlassian.bitbucket.scm.git.command;

import com.atlassian.bitbucket.commit.LastModifiedCallback;
import com.atlassian.bitbucket.repository.Branch;
import com.atlassian.bitbucket.repository.Repository;
import com.atlassian.bitbucket.scm.*;

import javax.annotation.Nonnull;

/**
 * Overrides methods from the standard {@link PluginExtendedCommandFactory} interface and returns {@link GitCommand}
 * instances instead of simple {@link Command} or {@link AsyncCommand} instances. This allows commands created by this
 * factory to be used synchronously or asynchronously at the caller's discretion, rather than fixing execution to one
 * approach or the other.
 * <p>
 * This interface does <i>not</i> add any commands to the standard interface. It only covariantly adjusts their return
 * types.
 *
 * @since 4.6
 */
public interface GitExtendedCommandFactory extends PluginExtendedCommandFactory {

    @Nonnull
    @Override
    GitCommand<Void> fork(@Nonnull Repository repository, @Nonnull ForkCommandParameters parameters);

    /**
     * @param repository the repository containing the starting commit
     * @param parameters parameters describing the path to stream modifications for, and the starting commit for
     *                   the traversal
     * @param callback   a callback to receive the latest commit for files in the specified path
     * @return a command to stream the latest commit to modify each files in the specified path, or {@code null} if
     *         streaming last modifications is not supported
     */
    @Nonnull
    @Override
    GitCommand<Void> lastModified(@Nonnull Repository repository, @Nonnull LastModifiedCommandParameters parameters,
                                  @Nonnull LastModifiedCallback callback);

    @Nonnull
    @Override
    GitCommand<Branch> merge(@Nonnull Repository repository, @Nonnull MergeCommandParameters parameters);

    @Nonnull
    @Override
    GitCommand<Void> updateDefaultBranch(@Nonnull Repository repository,
                                         @Nonnull UpdateDefaultBranchCommandParameters parameters);
}
