package com.atlassian.bitbucket.mesh.repair;

import com.atlassian.bitbucket.mesh.network.MeshNode;
import com.atlassian.bitbucket.mesh.repository.ReplicaState;

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

public interface RepairManager {

    /**
     * Repairs the replica of the provided repository on {@code targetNode}, using the replica on {@code sourceNode}
     * as the repair source.
     * <p>
     * One of {@code sourceNode} or {@code targetNode} must correspond to the local node, but not both.
     *
     * @param repositoryId the repository to repair
     * @param sourceNodes  the replica nodes to use as the repair source
     * @param targetNode   the replica node to repair
     * @return the state of the replica on {@code targetNode} after repair has completed; {@link ReplicaState#UNKNOWN}
     *         if {@code sourceNode} is the local node and the local replica is not {@link ReplicaState#CONSISTENT}.
     * @throws IllegalArgumentException if neither {@code sourceNode} nor {@code targetNode} corresponds to the local
     *                                  node, or if both correspond to the local node.
     */
    @Nonnull
    ReplicaState repair(@Nonnull String repositoryId, @Nonnull Collection<MeshNode> sourceNodes,
                        @Nonnull MeshNode targetNode);

    /**
     * Repairs the replica of the provided repository on {@code targetNode}, using the replica on {@code sourceNode}
     * as the repair source.
     * <p>
     * One of {@code sourceNode} or {@code targetNode} must correspond to the local node, but not both.
     *
     * @param sourceRepositoryId the repository to repair from
     * @param sourceNodes        the replica nodes to use as the repair source
     * @param targetRepositoryId the repository to repair
     * @param targetNode         the replica node to repair
     * @return the state of the replica on {@code targetNode} after repair has completed; {@link ReplicaState#UNKNOWN}
     *         if {@code sourceNode} is the local node and the local replica is not {@link ReplicaState#CONSISTENT}.
     * @throws IllegalArgumentException if neither {@code sourceNode} nor {@code targetNode} corresponds to the local
     *                                  node, or if both correspond to the local node.
     */
    @Nonnull
    ReplicaState repair(@Nonnull String sourceRepositoryId, @Nonnull Collection<MeshNode> sourceNodes,
                        @Nonnull String targetRepositoryId, @Nonnull MeshNode targetNode);
}
