package ackhandler

import (
	
	
)

type packetNumberGenerator interface {
	Peek() protocol.PacketNumber
	// Pop pops the packet number.
	// It reports if the packet number (before the one just popped) was skipped.
	// It never skips more than one packet number in a row.
	Pop() (skipped bool, _ protocol.PacketNumber)
}

type sequentialPacketNumberGenerator struct {
	next protocol.PacketNumber
}

var _ packetNumberGenerator = &sequentialPacketNumberGenerator{}

func newSequentialPacketNumberGenerator( protocol.PacketNumber) packetNumberGenerator {
	return &sequentialPacketNumberGenerator{next: }
}

func ( *sequentialPacketNumberGenerator) () protocol.PacketNumber {
	return .next
}

func ( *sequentialPacketNumberGenerator) () (bool, protocol.PacketNumber) {
	 := .next
	.next++
	return false, 
}

// The skippingPacketNumberGenerator generates the packet number for the next packet
// it randomly skips a packet number every averagePeriod packets (on average).
// It is guaranteed to never skip two consecutive packet numbers.
type skippingPacketNumberGenerator struct {
	period    protocol.PacketNumber
	maxPeriod protocol.PacketNumber

	next       protocol.PacketNumber
	nextToSkip protocol.PacketNumber

	rng utils.Rand
}

var _ packetNumberGenerator = &skippingPacketNumberGenerator{}

func newSkippingPacketNumberGenerator(, ,  protocol.PacketNumber) packetNumberGenerator {
	 := &skippingPacketNumberGenerator{
		next:      ,
		period:    ,
		maxPeriod: ,
	}
	.generateNewSkip()
	return 
}

func ( *skippingPacketNumberGenerator) () protocol.PacketNumber {
	if .next == .nextToSkip {
		return .next + 1
	}
	return .next
}

func ( *skippingPacketNumberGenerator) () (bool, protocol.PacketNumber) {
	 := .next
	if .next == .nextToSkip {
		++
		.next += 2
		.generateNewSkip()
		return true, 
	}
	.next++ // generate a new packet number for the next packet
	return false, 
}

func ( *skippingPacketNumberGenerator) () {
	// make sure that there are never two consecutive packet numbers that are skipped
	.nextToSkip = .next + 3 + protocol.PacketNumber(.rng.Int31n(int32(2*.period)))
	.period = min(2*.period, .maxPeriod)
}