/*
 * Copyright 2000-2012 JetBrains s.r.o.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package git4idea.branch;

import git4idea.repo.GitRepository;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.List;

/**
 * <p>Executes various operations on Git branches: checkout, create new branch, merge, delete, compare.</p>
 * <p>All operations are asynchronous and can be called from the EDT: the GitBrancher will start a background task.</p>
 * <p>It also takes care of analyzing results and notifying the user.</p>
 * <p>All operations can be called for multiple repositories at once.</p>
 *
 * @author Kirill Likhodedov
 */
public interface GitBrancher {

  /**
   * <p>Checks out a new branch in background.
   *    If there are unmerged files, proposes to resolve the conflicts and tries to check out again.</p>
   * <p>Doesn't check the name of new branch for validity -
   *    do this before calling this method, otherwise a standard error dialog will be shown.</p>
   * <p>Equivalent to {@code git checkout <name>}</p>
   *
   * @param name          name of the new branch to check out.
   * @param repositories  repositories to operate on.
   */
  void checkoutNewBranch(@NotNull String name, @NotNull List<GitRepository> repositories);

  /**
   * <p>Creates new tag on the selected reference.</p>
   *
   * @param name           the name of new tag.
   * @param reference      the reference which tag will point to.
   * @param repositories   repositories to operate on.
   * @param callInAwtLater the Runnable that should be called after execution of the method (both successful and unsuccessful).
   *                       If given, it will be called in the EDT {@link javax.swing.SwingUtilities#invokeLater(Runnable) later}.
   */
  void createNewTag(@NotNull String name, @NotNull String reference, @NotNull List<GitRepository> repositories,
                    @Nullable Runnable callInAwtLater);

  /**
   * <p>Checks out the given reference (a branch, or a reference name, or a commit hash).
   *    If local changes prevent the checkout, shows the list of them and proposes to make a "smart checkout":
   *    stash-checkout-unstash.</p>
   * <p>Doesn't check the reference for validity.</p>
   *
   * @param reference      reference to be checked out.
   * @param repositories   repositories to operate on.
   * @param callInAwtLater the Runnable that should be called after execution of the method (both successful and unsuccessful).
   *                       If given, it will be called in the EDT {@link javax.swing.SwingUtilities#invokeLater(Runnable) later}.
   */
  void checkout(@NotNull String reference, @NotNull List<GitRepository> repositories, @Nullable Runnable callInAwtLater);

  /**
   * Creates and checks out a new local branch starting from the given reference:
   * {@code git checkout -b <branchname> <start-point>}. <br/>
   * Provides the "smart checkout" procedure the same as in {@link #checkout(String, java.util.List, Runnable)}.
   *
   * @param newBranchName  the name of the new local branch.
   * @param startPoint     the reference to checkout.
   * @param repositories   repositories to operate on.
   * @param callInAwtLater the Runnable that should be called after execution of the method (both successful and unsuccessful).
   *                       If given, it will be called in the EDT {@link javax.swing.SwingUtilities#invokeLater(Runnable) later}.
   */
  void checkoutNewBranchStartingFrom(@NotNull String newBranchName, @NotNull String startPoint, @NotNull List<GitRepository> repositories,
                                     @Nullable Runnable callInAwtLater);

  /**
   * <p>Deletes the branch with the specified name.</p>
   * <p>{@code git branch -d <name>}</p>
   * <p>If the branch can't be deleted, because it is unmerged neither to the HEAD nor to its upstream,
   *    displays a dialog showing commits that are not merged and proposing to execute force deletion:</p>
   * <p>{@code git branch -D <name>}</p>
   *
   * @param branchName   the name of the branch to be deleted.
   * @param repositories repositories to operate on.
   */
  void deleteBranch(@NotNull String branchName, @NotNull List<GitRepository> repositories);

  /**
   * <p>Deletes the remote branch:</p>
   * <p>{@code git push <remote> :<name>}</p>
   *
   * @param branchName   name of the remote branch to delete.
   * @param repositories Repositories to operate on.
   */
  void deleteRemoteBranch(@NotNull String branchName, @NotNull List<GitRepository> repositories);

  /**
   * Compares the HEAD with the specified branch - shows a dialog with the differences.
   *
   * @param branchName         name of the branch to compare with.
   * @param repositories       repositories to operate on.
   * @param selectedRepository current or selected repository.
   *                           The list of commits is displayed for the repository selected from the combobox.
   *                           This parameter tells which repository should be pre-selected in the combobox.
   */
  void compare(@NotNull String branchName, @NotNull List<GitRepository> repositories, @NotNull GitRepository selectedRepository);

  /**
   * <p>Merges the given branch to the HEAD.</p>
   * <p>{@code git merge <name>}</p>
   * <p>If local changes prevent merging, proposes the "Smart merge" procedure (stash-merge-unstash).</p>
   * <p>If untracked files prevent merging, shows them in an error dialog.</p>
   *
   * @param branchName    the branch to be merged into HEAD.
   * @param deleteOnMerge specify whether the branch should be automatically deleted or proposed to be deleted after merge.
   * @param repositories  repositories to operate on.
   */
  void merge(@NotNull String branchName, @NotNull DeleteOnMergeOption deleteOnMerge, @NotNull List<GitRepository> repositories);

  /**
   * What should be done after successful merging a branch: delete the merged branch, propose to delete or do nothing.
   */
  enum DeleteOnMergeOption {
    /**
     * Delete the merged branch automatically.
     */
    DELETE,
    /**
     * Propose to delete the merged branch.
     */
    PROPOSE,
    /**
     * Do nothing, for example, when a remote branch has been merged, or when the {@code master} has been merged.
     */
    NOTHING
  }

}
