namespace NATS.Server.Raft;

/// <summary>
/// Type of membership change operation.
/// Go reference: raft.go:2500-2600 (ProposeAddPeer/RemovePeer)
/// </summary>
public enum RaftMembershipChangeType
{
    AddPeer,
    RemovePeer,
}

/// <summary>
/// Represents a pending RAFT membership change (add or remove peer).
/// Serialized as "{Type}:{PeerId}" in log entry commands for wire compatibility.
/// Go reference: raft.go:2500-2600 (membership change proposals)
/// </summary>
public readonly record struct RaftMembershipChange(RaftMembershipChangeType Type, string PeerId)
{
    /// <summary>
    /// Encodes this membership change as a log entry command string.
    /// Format: "AddPeer:node-id" or "RemovePeer:node-id"
    /// </summary>
    public string ToCommand() => $"{Type}:{PeerId}";

    /// <summary>
    /// Parses a log entry command string back into a membership change.
    /// Returns null if the command is not a membership change.
    /// </summary>
    public static RaftMembershipChange? TryParse(string command)
    {
        var colonIndex = command.IndexOf(':');
        if (colonIndex < 0)
            return null;

        var typePart = command[..colonIndex];
        var peerPart = command[(colonIndex + 1)..];

        if (string.IsNullOrEmpty(peerPart))
            return null;

        return typePart switch
        {
            nameof(RaftMembershipChangeType.AddPeer) => new RaftMembershipChange(RaftMembershipChangeType.AddPeer, peerPart),
            nameof(RaftMembershipChangeType.RemovePeer) => new RaftMembershipChange(RaftMembershipChangeType.RemovePeer, peerPart),
            _ => null,
        };
    }
}
