import time


class ReceiveRequest(object):
    """
    A ReceiveRequest is generated every time the first packet from a message is received.  The ReceiveRequest
     then keeps track of all of the message's packets that have already ben received.
    """

    def __init__(self, inital_packet, (host, port)):

        self.packets = set()
        self.total_packets = inital_packet.total_packets

        self.sequence_number = inital_packet.sequence_number
        self.hash = inital_packet.hash
        self.start_time = time.time()
        self.register_packet(inital_packet)

        self.host = host
        self.port = port

    def complete(self):
        """
        Returns True if this receive request has received all of its required packets
        :return:
        """
        return len(self.packets) == self.total_packets

    def get_payload(self):
        """
        Call this after completed.  Will return the original payload
        """
        self.packets = list(self.packets)
        self.packets = sorted(self.packets, key=lambda pkt: pkt.packet_number)
        payload = []
        for packet in self.packets:
            payload.append(packet.payload)
        return ''.join(payload)

    def owns_packet(self, packet):
        """
        This function returns True if this ReceiveRequest corresponds to the given packet
        :param packet: a Packet
        """
        return self.hash == packet.hash \
               and self.sequence_number == packet.sequence_number

    def register_packet(self, packet):
        self.packets.add(packet)

    def packets_observed(self):
        return len(self.packets)

    def __eq__(self, other):
        return self.sequence_number == other.sequence_number \
               and self.hash == other.hash

    def __hash__(self):
        return hash(self.hash)
