import umsgpack
import uuid

class Message:
    _type = None
    def __init__(self, sender = "", data = {}):
        self._sender = sender
        self._data = data

    @property
    def sender(self):
        return self._sender

    @sender.setter
    def sender(self, value):
        self._sender = value

    @property
    def data(self):
        return self._data

    # I love using keywords...
    @property
    def type(self):
        return self._type

    @type.setter
    def type(self, value):
        self._type = value

    def serialise(self):
        return umsgpack.packb({"type":self.type, "sender": self.sender, "data": self.data})

# SHould make this static in Message class.
def deserialise(obj):
    """
    Deserialises a given messagepack object into a Message.
    """
    m = Message()
    unpacked = umsgpack.unpackb(obj)
    print('Unpacked Object')
    print(unpacked)
    m.type = unpacked["type"]
    m._sender = unpacked["sender"]
    m._data = unpacked["data"]
    return m

class RequestLeader(Message):
    _type = "RequestLeader"

class ProposeMessage(Message):
    _type = "Propose"

class ElectionVote(Message):
    _type = "Elect"

class Commit(Message):
    _type = "Commit"

class ConnectSwarm(Message):
    _type = "connect"

class RequestVote(Message):
    _type = "reqvote"

class ConnectResponse(Message):
    _type = "accepted"

class VoterWill(Message):
    _type = "disconnectedvoter"

class CommanderWill(Message):
    _type = "disconnectedcommander"

class SubmitVote(Message):
    _type = "vote"

    def __init__(self, vote = None, sender = "", data = {}):
        Message.__init__(self, sender, data)
        self._data["vote"] = vote

    @property
    def vote(self):
        return self._data["vote"]

    @vote.setter
    def vote(self, value):
        self._data["vote"] = value

class GetSwarmParticipants(Message):
    _type = "listening"