# Path: src/lifeRaft/states/voter.py
# class Voter(State):
# 
#     def __init__(self, timeout=1.0):
#         super(Voter, self).__init__(timeout=timeout)
#         self._last_vote = None
# 
#     def on_vote_request(self, message):
#         if(self._last_vote is None and
#            message.data["lastLogIndex"] >= self._server._lastLogIndex):
#             self._last_vote = message.sender
#             self._send_vote_response_message(message)
#         else:
#             self._send_vote_response_message(message, yes=False)
# 
#         return self, None
# 
#     def _send_vote_response_message(self, msg, yes=True):
#         voteResponse = RequestVoteResponseMessage(
#             self._server._name,
#             msg.sender,
#             msg.term,
#             {"response": yes})
#         self._server.send_message_response(voteResponse)
#     
#     def on_client_message(self, message):
#         ''' return the message response for the client '''
#         return ClientFollowerResponse(message.sender, self._last_vote)
# 
# Path: src/lifeRaft/messages/append_entries.py
# class AppendEntriesMessage(BaseMessage):
# 
#     _type = BaseMessage.AppendEntries
# 
#     def __init__(self, sender, receiver, term, data):
#         BaseMessage.__init__(self, sender, receiver, term, data)
# 
# Path: src/lifeRaft/messages/client.py
# class ClientMessage(object):
#     # Types
#     Leader = 0
#     Append = 1
# 
#     def __init__(self, sender, receiver_host, receiver_port, command):
#         self._snd_id = sender
#         self._rcv_host = receiver_host
#         self._rcv_port = receiver_port
#         self._command = command
# 
#     @property
#     def command(self):
#         return self._command
# 
#     @property
#     def sender(self):
#         return self._snd_id
# 
#     @property
#     def receiver_host(self):
#         return self._receiver_host
# 
#     @property
#     def receiver_port(self):
#         return self._receiver_port
# 
# class ClientLeaderResponse(ClientResponse):
#     def __init__(self, receiver_id, leader_id, response):
#         super(ClientLeaderResponse, self).__init__(receiver_id, leader_id, response)


from collections import defaultdict
from .voter import Voter
from ..messages.append_entries import AppendEntriesMessage
from ..messages.client import ClientMessage, ClientLeaderResponse
            from .follower import Follower
            self._nextIndexes[n._name] = self._server._lastLogIndex + 1
            self._matchIndex[n._name] = 0

    def on_append_entries(self, message):
        if message.sender == self._server._name:
            # bcast
            return self, None
        if message.term > self._server._currentTerm:
            ## If we're getting append messages from the future, we're not the leader
            follower = Follower()
            follower.set_server(self._server)
            return follower, None
        raise RuntimeError

    def on_vote_received(self, message):
        ''' Well I find it dandy you're still voting for me '''
        return self, None

    def on_response_received(self, message):
        # Was the last AppendEntries good?
        if(not message.data["response"]):
            # No, so lets back up the log for this node
            self._nextIndexes[message.sender] -= 1

            # Get the next log entry to send to the client.
            previousIndex = max(0, self._nextIndexes[message.sender] - 1)
            previous = self._server._log[previousIndex]
            current = self._server._log[self._nextIndexes[message.sender]]

            # Send the new log to the client and wait for it to respond.

# Path: src/lifeRaft/states/voter.py
# class Voter(State):
# 
#     def __init__(self, timeout=1.0):
#         super(Voter, self).__init__(timeout=timeout)
#         self._last_vote = None
# 
#     def on_vote_request(self, message):
#         if(self._last_vote is None and
#            message.data["lastLogIndex"] >= self._server._lastLogIndex):
#             self._last_vote = message.sender
#             self._send_vote_response_message(message)
#         else:
#             self._send_vote_response_message(message, yes=False)
# 
#         return self, None
# 
#     def _send_vote_response_message(self, msg, yes=True):
#         voteResponse = RequestVoteResponseMessage(
#             self._server._name,
#             msg.sender,
#             msg.term,
#             {"response": yes})
#         self._server.send_message_response(voteResponse)
#     
#     def on_client_message(self, message):
#         ''' return the message response for the client '''
#         return ClientFollowerResponse(message.sender, self._last_vote)
# 
# Path: src/lifeRaft/messages/append_entries.py
# class AppendEntriesMessage(BaseMessage):
# 
#     _type = BaseMessage.AppendEntries
# 
#     def __init__(self, sender, receiver, term, data):
#         BaseMessage.__init__(self, sender, receiver, term, data)
# 
# Path: src/lifeRaft/messages/client.py
# class ClientMessage(object):
#     # Types
#     Leader = 0
#     Append = 1
# 
#     def __init__(self, sender, receiver_host, receiver_port, command):
#         self._snd_id = sender
#         self._rcv_host = receiver_host
#         self._rcv_port = receiver_port
#         self._command = command
# 
#     @property
#     def command(self):
#         return self._command
# 
#     @property
#     def sender(self):
#         return self._snd_id
# 
#     @property
#     def receiver_host(self):
#         return self._receiver_host
# 
#     @property
#     def receiver_port(self):
#         return self._receiver_port
# 
# class ClientLeaderResponse(ClientResponse):
#     def __init__(self, receiver_id, leader_id, response):
#         super(ClientLeaderResponse, self).__init__(receiver_id, leader_id, response)


# Path: src/lifeRaft/states/leader.py
from collections import defaultdict
from .voter import Voter
from ..messages.append_entries import AppendEntriesMessage
from ..messages.client import ClientMessage, ClientLeaderResponse
            from .follower import Follower

            self._nextIndexes[n._name] = self._server._lastLogIndex + 1
            self._matchIndex[n._name] = 0

    def on_append_entries(self, message):
        if message.sender == self._server._name:
            # bcast
            return self, None
        if message.term > self._server._currentTerm:
            ## If we're getting append messages from the future, we're not the leader
            follower = Follower()
            follower.set_server(self._server)
            return follower, None
        raise RuntimeError

    def on_vote_received(self, message):
        ''' Well I find it dandy you're still voting for me '''
        return self, None

    def on_response_received(self, message):
        # Was the last AppendEntries good?
        if(not message.data["response"]):
            # No, so lets back up the log for this node
            self._nextIndexes[message.sender] -= 1

            # Get the next log entry to send to the client.
            previousIndex = max(0, self._nextIndexes[message.sender] - 1)
            previous = self._server._log[previousIndex]
            current = self._server._log[self._nextIndexes[message.sender]]

            # Send the new log to the client and wait for it to respond.

            appendEntry = AppendEntriesMessage(