package wire

import (
	
	
	
	

	
	
)

var errInvalidAckRanges = errors.New("AckFrame: ACK frame contains invalid ACK ranges")

// An AckFrame is an ACK frame
type AckFrame struct {
	AckRanges []AckRange // has to be ordered. The highest ACK range goes first, the lowest ACK range goes last
	DelayTime time.Duration

	ECT0, ECT1, ECNCE uint64
}

// parseAckFrame reads an ACK frame
func parseAckFrame( *AckFrame,  []byte,  FrameType,  uint8,  protocol.Version) (int, error) {
	 := len()
	 :=  == FrameTypeAckECN

	, ,  := quicvarint.Parse()
	if  != nil {
		return 0, replaceUnexpectedEOF()
	}
	 = [:]
	 := protocol.PacketNumber()
	, ,  := quicvarint.Parse()
	if  != nil {
		return 0, replaceUnexpectedEOF()
	}
	 = [:]

	 := time.Duration(*1<<) * time.Microsecond
	if  < 0 {
		// If the delay time overflows, set it to the maximum encode-able value.
		 = time.Duration(math.MaxInt64)
	}
	.DelayTime = 

	, ,  := quicvarint.Parse()
	if  != nil {
		return 0, replaceUnexpectedEOF()
	}
	 = [:]

	// read the first ACK range
	, ,  := quicvarint.Parse()
	if  != nil {
		return 0, replaceUnexpectedEOF()
	}
	 = [:]
	 := protocol.PacketNumber()
	if  >  {
		return 0, errors.New("invalid first ACK range")
	}
	 :=  - 
	.AckRanges = append(.AckRanges, AckRange{Smallest: , Largest: })

	// read all the other ACK ranges
	for range  {
		, ,  := quicvarint.Parse()
		if  != nil {
			return 0, replaceUnexpectedEOF()
		}
		 = [:]
		 := protocol.PacketNumber()
		if  < +2 {
			return 0, errInvalidAckRanges
		}
		 :=  -  - 2

		, ,  := quicvarint.Parse()
		if  != nil {
			return 0, replaceUnexpectedEOF()
		}
		 = [:]
		 := protocol.PacketNumber()

		if  >  {
			return 0, errInvalidAckRanges
		}
		 =  - 
		.AckRanges = append(.AckRanges, AckRange{Smallest: , Largest: })
	}

	if !.validateAckRanges() {
		return 0, errInvalidAckRanges
	}

	if  {
		, ,  := quicvarint.Parse()
		if  != nil {
			return 0, replaceUnexpectedEOF()
		}
		 = [:]
		.ECT0 = 
		, ,  := quicvarint.Parse()
		if  != nil {
			return 0, replaceUnexpectedEOF()
		}
		 = [:]
		.ECT1 = 
		, ,  := quicvarint.Parse()
		if  != nil {
			return 0, replaceUnexpectedEOF()
		}
		 = [:]
		.ECNCE = 
	}

	return  - len(), nil
}

// Append appends an ACK frame.
func ( *AckFrame) ( []byte,  protocol.Version) ([]byte, error) {
	 := .ECT0 > 0 || .ECT1 > 0 || .ECNCE > 0
	if  {
		 = append(, byte(FrameTypeAckECN))
	} else {
		 = append(, byte(FrameTypeAck))
	}
	 = quicvarint.Append(, uint64(.LargestAcked()))
	 = quicvarint.Append(, encodeAckDelay(.DelayTime))

	 := min(len(.AckRanges), protocol.MaxNumAckRanges)
	 = quicvarint.Append(, uint64(-1))

	// write the first range
	,  := .encodeAckRange(0)
	 = quicvarint.Append(, )

	// write all the other range
	for  := 1;  < ; ++ {
		,  := .encodeAckRange()
		 = quicvarint.Append(, )
		 = quicvarint.Append(, )
	}

	if  {
		 = quicvarint.Append(, .ECT0)
		 = quicvarint.Append(, .ECT1)
		 = quicvarint.Append(, .ECNCE)
	}
	return , nil
}

// Length of a written frame
func ( *AckFrame) ( protocol.Version) protocol.ByteCount {
	 := .AckRanges[0].Largest

	// The number of ACK ranges is limited to 64, which guarantees that the
	// ACK Range Count value can be encoded in a single byte varint.
	 := 1 + quicvarint.Len(uint64()) + quicvarint.Len(encodeAckDelay(.DelayTime)) + 1

	 := .AckRanges[0].Smallest
	 += quicvarint.Len(uint64( - ))

	for  := 1;  < min(len(.AckRanges), protocol.MaxNumAckRanges); ++ {
		,  := .encodeAckRange()
		 += quicvarint.Len()
		 += quicvarint.Len()
	}
	if .ECT0 > 0 || .ECT1 > 0 || .ECNCE > 0 {
		 += quicvarint.Len(.ECT0) + quicvarint.Len(.ECT1) + quicvarint.Len(.ECNCE)
	}
	return protocol.ByteCount()
}

// Truncate truncates the ACK frame to fit into maxSize,
// and to at most 64 ACK ranges.
// maxSize must be large enough to fit at least one ACK range.
func ( *AckFrame) ( protocol.ByteCount,  protocol.Version) {
	.AckRanges = .AckRanges[:.numEncodableAckRanges()]
}

// gets the number of ACK ranges that can be encoded
// such that the resulting frame is smaller than maxSize
func ( *AckFrame) ( protocol.ByteCount) int {
	// Fast path: Most ACK frames are relatively small, and we don't need to calculate the exact length.
	// We just assume the worst case scenario: every varint is encoded to 8 bytes.
	// If the result is still smaller than the maximum ACK frame size, the actual ACK frame will definitely fit.
	 := 1 + 8 /* largest acked */ + 8 /* delay */ + 1 /* ack range count */ + 8 /* first range */
	if .ECT0 > 0 || .ECT1 > 0 || .ECNCE > 0 {
		 += 8 + 8 + 8
	}
	 := min(len(.AckRanges), protocol.MaxNumAckRanges)
	 += 2 * 8 * ( - 1)
	if protocol.ByteCount() <=  {
		return 
	}

	// Slow path: Calculate the exact length of the ACK frame.
	 = 1 + quicvarint.Len(uint64(.LargestAcked())) + quicvarint.Len(encodeAckDelay(.DelayTime)) + 1
	,  := .encodeAckRange(0)
	 += quicvarint.Len()
	if .ECT0 > 0 || .ECT1 > 0 || .ECNCE > 0 {
		 += quicvarint.Len(.ECT0) + quicvarint.Len(.ECT1) + quicvarint.Len(.ECNCE)
	}
	for  := 1;  < ; ++ {
		,  := .encodeAckRange()
		 := quicvarint.Len() + quicvarint.Len()
		if protocol.ByteCount(+) >  {
			// Writing range i would exceed the maximum size,
			// so encode one range less than that.
			return 
		}
		 += 
	}
	return 
}

func ( *AckFrame) ( int) (,  uint64) {
	if  == 0 {
		return 0, uint64(.AckRanges[0].Largest - .AckRanges[0].Smallest)
	}
	return uint64(.AckRanges[-1].Smallest - .AckRanges[].Largest - 2),
		uint64(.AckRanges[].Largest - .AckRanges[].Smallest)
}

// HasMissingRanges returns if this frame reports any missing packets
func ( *AckFrame) () bool {
	return len(.AckRanges) > 1
}

func ( *AckFrame) () bool {
	if len(.AckRanges) == 0 {
		return false
	}

	// check the validity of every single ACK range
	for ,  := range .AckRanges {
		if .Smallest > .Largest {
			return false
		}
	}

	// check the consistency for ACK with multiple ACK ranges
	for ,  := range .AckRanges {
		if  == 0 {
			continue
		}
		 := .AckRanges[-1]
		if .Smallest <= .Smallest {
			return false
		}
		if .Smallest <= .Largest+1 {
			return false
		}
	}

	return true
}

// LargestAcked is the largest acked packet number
func ( *AckFrame) () protocol.PacketNumber {
	return .AckRanges[0].Largest
}

// LowestAcked is the lowest acked packet number
func ( *AckFrame) () protocol.PacketNumber {
	return .AckRanges[len(.AckRanges)-1].Smallest
}

// AcksPacket determines if this ACK frame acks a certain packet number
func ( *AckFrame) ( protocol.PacketNumber) bool {
	if  < .LowestAcked() ||  > .LargestAcked() {
		return false
	}

	 := sort.Search(len(.AckRanges), func( int) bool {
		return  >= .AckRanges[].Smallest
	})
	// i will always be < len(f.AckRanges), since we checked above that p is not bigger than the largest acked
	return  <= .AckRanges[].Largest
}

func ( *AckFrame) () {
	.DelayTime = 0
	.ECT0 = 0
	.ECT1 = 0
	.ECNCE = 0
	for ,  := range .AckRanges {
		.Largest = 0
		.Smallest = 0
	}
	.AckRanges = .AckRanges[:0]
}

func encodeAckDelay( time.Duration) uint64 {
	return uint64(.Nanoseconds() / (1000 * (1 << protocol.AckDelayExponent)))
}