package com.atlassian.bitbucket.cluster;

import javax.annotation.Nonnull;
import java.net.InetSocketAddress;

/**
 * Describes a single node in a cluster.
 */
public interface ClusterNode {

    /**
     * @return the complete socket address, comprised of hostname and port, for the node
     */
    @Nonnull
    InetSocketAddress getAddress();

    /**
     * Retrieves a cluster-wide unique identifier for this node.
     * <p>
     * <b>Warning</b>: Plugins should make <i>no assumptions</i> about this ID. That includes:
     * <ul>
     *     <li>How long it is</li>
     *     <li>What characters it contains</li>
     *     <li>Whether it will be consistent across restarts. Don't persist long-term data against these IDs</li>
     * </ul>
     * The value is guaranteed to be unique within the cluster. If the cluster is restarted, every node's ID will
     * still be unique but will likely not be the same as the previous value.
     *
     * @return a cluster-wide unique identifier for this node
     */
    @Nonnull
    String getId();

    /**
     * Retrieves a unique identifier for this node that remains stable while the node is running.
     * <p>
     * The value is guaranteed to be unique within the cluster. Unlike the ordinary {@link #getId() identifier}, if the
     * node leaves and joins the cluster, this value remains the same.
     *
     * @return a cluster-wide unique identifier for this node that remains stable while the node is running
     * @since 4.8
     */
    @Nonnull
    String getVmId();

    /**
     * @return {@code true} if this node has fully started up; {@code false} otherwise
     * @since 4.8
     */
    boolean isFullyStarted();

    /**
     * @return {@code true} if this is the {@link ClusterInformation#getLocalNode() local node}; otherwise,
     *         {@code false} for remote nodes
     */
    boolean isLocal();

    /**
     * A long living cluster name that is defined by setting the system property {@code cluster.node.name}
     * @return The value from the system property named above otherwise an empty string if the property is not set.
     */
    @Nonnull
    String getName();
}
