package com.atlassian.bitbucket.mesh.test.cluster;

import com.google.errorprone.annotations.MustBeClosed;
import io.grpc.ManagedChannel;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

/**
 * SPI used by {@link MeshClusterManager} to register / unregister Mesh nodes with the application.
 */
public interface MeshControlPlane {

    /**
     * Opens a {@link ManagedChannel} to the specified {@link MeshClusterNode}, which can be used to verify the node
     * has successfully started.
     * <p>
     * <b>Note</b>: The caller must {@link ManagedChannel#shutdown shutdown} the returned channel to avoid leaking
     * resources. The returned channel is not otherwise retained (for example, it's not used by other RPC requests
     * to the node).
     *
     * @param node the node to open a channel for
     * @return a channel for the specified node, which may or may not be ready to process requests
     */
    @MustBeClosed
    @Nonnull
    ManagedChannel openChannel(@Nonnull MeshClusterNode node);

    /**
     * @param node the node to register
     * @return the ID under which the node was registered with the control plane; {@code null} if the node could not
     *         be registered with the control plane
     */
    @Nullable
    String registerNode(@Nonnull MeshClusterNode node);

    /**
     * @param node the node to unregister
     * @return {@code true} if the node was unregistered; {@code false} if the node was not registered
     */
    boolean unregisterNode(@Nonnull MeshClusterNode node);
}
