/* Convert from one state to another. */

#ifndef CONVERT_H_
#define CONVERT_H_

#include "../include/raft.h"

/* Convert from unavailable, or candidate or leader to follower.
 *
 * From Figure 3.1:
 *
 *   If election timeout elapses without receiving AppendEntries RPC from
 *   current leader or granting vote to candidate: convert to candidate.
 *
 * The above implies that we need to reset the election timer when converting to
 * follower. */
void convertToFollower(struct raft *r);

/* Convert from follower to candidate, starting a new election.
 *
 * From Figure 3.1:
 *
 *   On conversion to candidate, start election
 *
 * If the disrupt_leader flag is true, the server will set the disrupt leader
 * flag of the RequestVote messages it sends.
 *
 * Errors:
 *
 * RAFT_NOMEM
 *     Memory for the votes array could not be allocated.
 */
int convertToCandidate(struct raft *r, bool disrupt_leader);

/* Convert from candidate to leader.
 *
 * From Figure 3.1:
 *
 *   Upon election: send initial empty AppendEntries RPC (heartbeat) to each
 *   server.
 *
 * From Section 3.4:
 *
 *   Once a candidate wins an election, it becomes leader. It then sends
 *   heartbeat messages to all of the other servers to establish its authority
 *   and prevent new elections.
 *
 * From Section 3.3:
 *
 *   The leader maintains a nextIndex for each follower, which is the index
 *   of the next log entry the leader will send to that follower. When a
 *   leader first comes to power, it initializes all nextIndex values to the
 *   index just after the last one in its log.
 * Errors:
 *
 * RAFT_NOMEM
 *     Memory for the progress array or for the initial no-op entry could
 *     not be allocated.
 */
int convertToLeader(struct raft *r);

/* Clear the current state */
void convertClear(struct raft *r);

#endif /* CONVERT_H_ */
