package com.atlassian.bitbucket.pull;

import javax.annotation.Nonnull;
import java.util.Optional;

/**
 * Describes a strategy for merging a pull request. Some strategies may only merge <i>changes</i>, producing
 * one or more new commits, while others might merge <i>commits</i>, applying the pull request's commits to
 * its target. Each strategy includes a brief {@link #getDescription description} to help explain its approach
 * to performing merges.
 *
 * @since 4.9
 */
public interface PullRequestMergeStrategy {

    /**
     * Retrieves a short, descriptive summary of how the strategy performs merges, which can be used to help
     * choose between available strategies.
     *
     * @return a short, descriptive summary the strategy
     */
    @Nonnull
    String getDescription();

    /**
     * Retrieves a well-known flag, or combination of flags, associated with the strategy, which may be helpful
     * in associating the strategy with the behavior of a command line client. Some strategies, which are built
     * by extending or overriding standard SCM functionality, may not have flags associated with them.
     *
     * @return a well-known flag, or combination of flags, associated with the strategy, which may be
     *         {@code Optional.empty()} if such flags don't exist, but never {@code null}
     */
    @Nonnull
    Optional<String> getFlag();

    /**
     * Retrieves the strategy's unique identifier, which is used to {@link PullRequestMergeRequest#getStrategyId
     * request the strategy} when merging a pull request.
     *
     * @return a unique identifier for the strategy, used to request the strategy when merging
     */
    @Nonnull
    String getId();

    /**
     * Retrieves the strategy's name.
     *
     * @return the strategy's name
     */
    @Nonnull
    String getName();

    /**
     * Retrieves a flag indicating whether or not the strategy is enabled. Only enabled strategies may be
     * {@link PullRequestMergeRequest#getStrategyId() requested} when merging pull requests. Each repository
     * is <i>guaranteed</i> to have <i>at least one</i> enabled strategy.
     * <p>
     * Administrators can configure the set of strategies they want to be available for pull requests in their
     * repositories and may choose to enable a single strategy, to ensure all pull requests are merged the same
     * way, or multiple strategies, to allow the most appropriate strategy to be selected at merge time based
     * on the particulars of the pull request being merged.
     *
     * @return {@code true} if this strategy is enabled and may be requested when merging a pull request; otherwise,
     *         {@code false} if an administrator has disabled this strategy
     */
    boolean isEnabled();
}
