package com.atlassian.bitbucket.mesh.transaction;

import com.atlassian.bitbucket.mesh.network.MeshNode;
import com.atlassian.bitbucket.mesh.rpc.v1.RpcRepositoryConsistencySummary;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.concurrent.CompletionStage;

/**
 * Represents one replica's participation in the {@code RepositoryService/VerifyConsistency} operations. In this
 * process, all replicas coordinate to acquire a write lock for the repository, and while holding the lock compare
 * their local version and hashes to discover any inconsistencies that may have been introduced after one or more
 * nodes recovered from backup or failover.
 *
 * @since 1.2
 * @see ReplicaConsistencyVerifier
 */
public interface ReplicaConsistencyVerifier {

    /**
     * @param message the cancellation message
     */
    void cancel(@Nullable String message);

    /**
     * @return the replica this is the verifier for
     */
    @Nonnull
    MeshNode getReplica();

    /**
     * Requests the replica to acquire the write token for the specified repository and to return its replica version
     * details while holding the lock.
     *
     * @param repositoryId     the repository
     * @param logicalTimestamp the logical timestamp of the token request
     */
    @Nonnull
    CompletionStage<Void> requestTokenAndReplicaVersion(@Nonnull String repositoryId, long logicalTimestamp);

    /**
     * Sends a consistency summary to the replica. This should be the final call on the replica. The replica will,
     * in response to this summary, update its internal replica consistency state and release the write lock.
     *
     * @param summary          the summary to send
     * @param logicalTimestamp the logical timestamp of the summary
     */
    void summarize(@Nonnull RpcRepositoryConsistencySummary summary, long logicalTimestamp);
}
