// Copyright 2023 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

//go:build go1.21

package quic

import (
	"time"
)

// ackState tracks packets received from a peer within a number space.
// It handles packet deduplication (don't process the same packet twice) and
// determines the timing and content of ACK frames.
type ackState struct {
	seen rangeset[packetNumber]

	// The time at which we must send an ACK frame, even if we have no other data to send.
	nextAck time.Time

	// The time we received the largest-numbered packet in seen.
	maxRecvTime time.Time

	// The largest-numbered ack-eliciting packet in seen.
	maxAckEliciting packetNumber

	// The number of ack-eliciting packets in seen that we have not yet acknowledged.
	unackedAckEliciting int
}

// shouldProcess reports whether a packet should be handled or discarded.
func (acks *ackState) shouldProcess(num packetNumber) bool {
	if packetNumber(acks.seen.min()) > num {
		// We've discarded the state for this range of packet numbers.
		// Discard the packet rather than potentially processing a duplicate.
		// https://www.rfc-editor.org/rfc/rfc9000.html#section-13.2.3-5
		return false
	}
	if acks.seen.contains(num) {
		// Discard duplicate packets.
		return false
	}
	return true
}

// receive records receipt of a packet.
func (acks *ackState) receive(now time.Time, space numberSpace, num packetNumber, ackEliciting bool) {
	if ackEliciting {
		acks.unackedAckEliciting++
		if acks.mustAckImmediately(space, num) {
			acks.nextAck = now
		} else if acks.nextAck.IsZero() {
			// This packet does not need to be acknowledged immediately,
			// but the ack must not be intentionally delayed by more than
			// the max_ack_delay transport parameter we sent to the peer.
			//
			// We always delay acks by the maximum allowed, less the timer
			// granularity. ("[max_ack_delay] SHOULD include the receiver's
			// expected delays in alarms firing.")
			//
			// https://www.rfc-editor.org/rfc/rfc9000#section-18.2-4.28.1
			acks.nextAck = now.Add(maxAckDelay - timerGranularity)
		}
		if num > acks.maxAckEliciting {
			acks.maxAckEliciting = num
		}
	}

	acks.seen.add(num, num+1)
	if num == acks.seen.max() {
		acks.maxRecvTime = now
	}

	// Limit the total number of ACK ranges by dropping older ranges.
	//
	// Remembering more ranges results in larger ACK frames.
	//
	// Remembering a large number of ranges could result in ACK frames becoming
	// too large to fit in a packet, in which case we will silently drop older
	// ranges during packet construction.
	//
	// Remembering fewer ranges can result in unnecessary retransmissions,
	// since we cannot accept packets older than the oldest remembered range.
	//
	// The limit here is completely arbitrary. If it seems wrong, it probably is.
	//
	// https://www.rfc-editor.org/rfc/rfc9000#section-13.2.3
	const maxAckRanges = 8
	if overflow := acks.seen.numRanges() - maxAckRanges; overflow > 0 {
		acks.seen.removeranges(0, overflow)
	}
}

// mustAckImmediately reports whether an ack-eliciting packet must be acknowledged immediately,
// or whether the ack may be deferred.
func (acks *ackState) mustAckImmediately(space numberSpace, num packetNumber) bool {
	// https://www.rfc-editor.org/rfc/rfc9000.html#section-13.2.1
	if space != appDataSpace {
		// "[...] all ack-eliciting Initial and Handshake packets [...]"
		// https://www.rfc-editor.org/rfc/rfc9000.html#section-13.2.1-2
		return true
	}
	if num < acks.maxAckEliciting {
		// "[...] when the received packet has a packet number less than another
		// ack-eliciting packet that has been received [...]"
		// https://www.rfc-editor.org/rfc/rfc9000.html#section-13.2.1-8.1
		return true
	}
	if acks.seen.rangeContaining(acks.maxAckEliciting).end != num {
		// "[...] when the packet has a packet number larger than the highest-numbered
		// ack-eliciting packet that has been received and there are missing packets
		// between that packet and this packet."
		// https://www.rfc-editor.org/rfc/rfc9000.html#section-13.2.1-8.2
		//
		// This case is a bit tricky. Let's say we've received:
		//   0, ack-eliciting
		//   1, ack-eliciting
		//   3, NOT ack eliciting
		//
		// We have sent ACKs for 0 and 1. If we receive ack-eliciting packet 2,
		// we do not need to send an immediate ACK, because there are no missing
		// packets between it and the highest-numbered ack-eliciting packet (1).
		// If we receive ack-eliciting packet 4, we do need to send an immediate ACK,
		// because there's a gap (the missing packet 2).
		//
		// We check for this by looking up the ACK range which contains the
		// highest-numbered ack-eliciting packet: [0, 1) in the above example.
		// If the range ends just before the packet we are now processing,
		// there are no gaps. If it does not, there must be a gap.
		return true
	}
	if acks.unackedAckEliciting >= 2 {
		// "[...] after receiving at least two ack-eliciting packets."
		// https://www.rfc-editor.org/rfc/rfc9000.html#section-13.2.2
		return true
	}
	return false
}

// shouldSendAck reports whether the connection should send an ACK frame at this time,
// in an ACK-only packet if necessary.
func (acks *ackState) shouldSendAck(now time.Time) bool {
	return !acks.nextAck.IsZero() && !acks.nextAck.After(now)
}

// acksToSend returns the set of packet numbers to ACK at this time, and the current ack delay.
// It may return acks even if shouldSendAck returns false, when there are unacked
// ack-eliciting packets whose ack is being delayed.
func (acks *ackState) acksToSend(now time.Time) (nums rangeset[packetNumber], ackDelay time.Duration) {
	if acks.nextAck.IsZero() && acks.unackedAckEliciting == 0 {
		return nil, 0
	}
	// "[...] the delays intentionally introduced between the time the packet with the
	// largest packet number is received and the time an acknowledgement is sent."
	// https://www.rfc-editor.org/rfc/rfc9000#section-13.2.5-1
	delay := now.Sub(acks.maxRecvTime)
	if delay < 0 {
		delay = 0
	}
	return acks.seen, delay
}

// sentAck records that an ACK frame has been sent.
func (acks *ackState) sentAck() {
	acks.nextAck = time.Time{}
	acks.unackedAckEliciting = 0
}

// handleAck records that an ack has been received for a ACK frame we sent
// containing the given Largest Acknowledged field.
func (acks *ackState) handleAck(largestAcked packetNumber) {
	// We can stop acking packets less or equal to largestAcked.
	// https://www.rfc-editor.org/rfc/rfc9000.html#section-13.2.4-1
	//
	// We rely on acks.seen containing the largest packet number that has been successfully
	// processed, so we retain the range containing largestAcked and discard previous ones.
	acks.seen.sub(0, acks.seen.rangeContaining(largestAcked).start)
}

// largestSeen reports the largest seen packet.
func (acks *ackState) largestSeen() packetNumber {
	return acks.seen.max()
}
