package com.atlassian.stash.internal.scm.git.upgrade;

import com.atlassian.bitbucket.repository.Repository;
import com.atlassian.bitbucket.user.SecurityService;

import javax.annotation.Nonnull;

/**
 * Describes common features between {@link SynchronousUpgradeTask synchronous} and {@link AsynchronousUpgradeTask
 * asynchronous} upgrade tasks. Direct implementations of this interface are not useful. Instead, tasks should
 * implement one of the derived interfaces, whichever is appropriate.
 *
 * @since 2.9
 */
public interface UpgradeTaskSupport {

    /**
     * Retrieves a short description of what the upgrade task does.
     * <p>
     * The description will be provided to the {@link SecurityService SecurityService} when
     * escalating permissions, and may also be written to the logs or stored in a database.
     *
     * @return a short description for this task
     */
    @Nonnull
    String getDescription();

    /**
     * Retrieves the <i>absolute order</i> in which this task should be applied relative to other tasks of the <i>same
     * type</i>. {@link AsynchronousUpgradeTask Asynchronous} and {@link SynchronousUpgradeTask synchronous} upgrade
     * tasks are applied separately and are <i>never interleaved</i>. Synchronous tasks are applied first, in order,
     * followed by asynchronous tasks, in order.
     * <p>
     * If multiple upgrade tasks of the same type have the same order, their effective order is <i>undefined</i> (but
     * will most likely default to their <i>injection order</i> in the {@link GitUpgradeManager}). Tasks should always
     * use a distinct, monotonically increasing value.
     *
     * @return the order in which this upgrade task should be run
     */
    int getOrder();

    /**
     * Applies an upgrade to the provided {@link Repository repository}
     *
     * @param repository the repository to upgrade
     */
    void upgrade(@Nonnull Repository repository) throws Exception;
}
