from time import time

class Queue:
    """Represents a drop-tail network bottleneck.

    Used by L{network.Network}, this class can ensure schedule packets to
    occur at a specified rate.  Optionally, it can have a finite queue size
    which will cause it to drop new packets whenever the queue is full.

    B{Do not modify or directly use this class for the problem set.}
    """

    def __init__( self, rate=0, queue_size=0):
        """Initialize the bottleneck.

        @param rate: The maximum number of packets per second this bottleneck
                     can handle.  0 = unlimited.
        @param queue_size: The maximum number of packets the bottleneck can
                            enqueue.  0 = unlimited.
        """
 
        if( rate > 0 ):
            self.ratedelay = 1.0/(1.0*rate)
        else:
            self.ratedelay = 0
        self.queue_size = queue_size
        self.last_sched = 0

    def schedulePacket( self ):
        """Enqueue a new packet.

        @return: The time at which to send the packet, or 0 if it should be
                 sent right away, or -1 if it should be dropped.

        """

        # we can figure out how big the queue is currently by comparing
        # the current time to the last_sched time
        curr_queue_size = -1
        if( self.queue_size > 0 and self.ratedelay > 0 ):
            curr_queue_size = round ((self.last_sched - time())/self.ratedelay)

        # if the network has a rate limit, schedule the packet to happen
        # 1/rate after the last packet that's been scheduled
        if( curr_queue_size < self.queue_size ):
            if( self.ratedelay > 0 ):
                if( time() > self.last_sched + self.ratedelay ):
                    self.last_sched = time()
                    return 0
                else:
                    self.last_sched = self.last_sched + self.ratedelay
                    return self.last_sched
            else:
                self.last_sched = time()
                return 0
        else:
            return -1


