package com.atlassian.bitbucket.scm.pull;

import com.atlassian.bitbucket.pull.PullRequestService;

import javax.annotation.Nonnull;

/**
 * Used to enforce a specific precondition for a merge operation.
 * <p>
 * Merge checks are called for:
 * <ul>
 *     <li>{@link PullRequestService#canMerge PullRequestService#canMerge}</li>
 *     <li>{@link PullRequestService#merge PullRequestService#merge}</li>
 * </ul>
 * {@link MergeRequest#isDryRun} can be used to determine which operation is in progress, for implementations which
 * should only be applied to one or the other (but most checks should apply the same way to both).
 */
public interface MergeRequestCheck {

    /**
     * Called when a merge has been requested, allowing plugins to apply custom rules to validate whether the merge
     * should proceed. If <i>any</i> {@code MergeRequestCheck} {@link MergeRequest#veto(String, String) vetoes} the
     * merge, it will not be performed. Veto messages from the failed checks will be shown to the merging user.
     * <p>
     * Implementations of this method <i>should not</i> throw exceptions. Exceptions are <i>not</i> considered vetoes;
     * they are considered an indication that the implementation is broken and will be logged and <i>ignored</i>, with
     * the merge is allowed to proceed unless another check happens to veto it.
     *
     * @param request the merge in progress
     */
    void check(@Nonnull MergeRequest request);
}
