package com.atlassian.bitbucket.internal.branch;

import com.atlassian.bitbucket.ForbiddenException;
import com.atlassian.bitbucket.repository.*;

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

/**
 * A service to operate on branches in a Git repository.
 *
 * @since 2.6
 */
public interface InternalBranchService extends BranchService {

    /**
     * Creates and returns a branch in a repository.
     *
     * @param repository the repository to create the branch
     * @param branchName the non-fully qualified branch name
     * @param startPoint the commit the new branch head will point to. It may a branch name, a commit ID, or a tag
     * @return the created branch
     * @throws ForbiddenException if the caller does not have write permission to the
     *         repository or there are branch permission restrictions preventing creation of the branch
     * @throws IllegalRepositoryStateException if the repository is not a Git SCM or
     *         if it is an empty repository
     * @throws DuplicateRefException if the branch already exists for the given repository
     * @throws InvalidRefNameException if {@code branchName} is missing or does not
     * satisfy Git's criteria for a valid ref name
     * @throws BranchStartPointValidationException if the startPoint is invalid or missing
     */
    @Nonnull
    Branch createBranch(@Nonnull Repository repository, @Nonnull String branchName, @Nonnull String startPoint);

    /**
     * Deletes a branch in a repository.
     *
     * @param repository the repository to create the branch
     * @param branchName the name of the branch to delete
     * @param endPoint an optional commit ID that the branch must match to be deleted
     * @param dryRun whether to only test if the branch can be deleted without performing any deletion
     * @throws ForbiddenException if the caller does not have write permission to the
     *         repository or there are branch permission restrictions preventing the deletion of the branch
     * @throws IllegalRepositoryStateException if the repository is not a Git repository
     * @throws InvalidRefNameException if the supplied branch name is a blank string
     * @throws BranchHasMovedException if the branch is not at the {@code endPoint}
     * @throws UnsupportedOnBranchException if the branch is the default branch of the repository
     */
    void deleteBranch(@Nonnull Repository repository, @Nonnull String branchName, @Nullable String endPoint, boolean dryRun);
}
