// 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 (
	"math"
	"time"
)

type lossState struct {
	side connSide

	// True when the handshake is confirmed.
	// https://www.rfc-editor.org/rfc/rfc9001#section-4.1.2
	handshakeConfirmed bool

	// Peer's max_ack_delay transport parameter.
	// https://www.rfc-editor.org/rfc/rfc9000.html#section-18.2-4.28.1
	maxAckDelay time.Duration

	// Time of the next event: PTO expiration (if ptoTimerArmed is true),
	// or loss detection.
	// The connection must call lossState.advance when the timer expires.
	timer time.Time

	// True when the PTO timer is set.
	ptoTimerArmed bool

	// True when the PTO timer has expired and a probe packet has not yet been sent.
	ptoExpired bool

	// Count of PTO expirations since the lack received acknowledgement.
	// https://www.rfc-editor.org/rfc/rfc9002#section-6.2.1-9
	ptoBackoffCount int

	// Anti-amplification limit: Three times the amount of data received from
	// the peer, less the amount of data sent.
	//
	// Set to antiAmplificationUnlimited (MaxInt) to disable the limit.
	// The limit is always disabled for clients, and for servers after the
	// peer's address is validated.
	//
	// Anti-amplification is per-address; this will need to change if/when we
	// support address migration.
	//
	// https://www.rfc-editor.org/rfc/rfc9000#section-8-2
	antiAmplificationLimit int

	// Count of non-ack-eliciting packets (ACKs) sent since the last ack-eliciting one.
	consecutiveNonAckElicitingPackets int

	rtt   rttState
	pacer pacerState
	cc    *ccReno

	// Per-space loss detection state.
	spaces [numberSpaceCount]struct {
		sentPacketList
		maxAcked         packetNumber
		lastAckEliciting packetNumber
	}

	// Temporary state used when processing an ACK frame.
	ackFrameRTT                  time.Duration // RTT from latest packet in frame
	ackFrameContainsAckEliciting bool          // newly acks an ack-eliciting packet?
}

const antiAmplificationUnlimited = math.MaxInt

func (c *lossState) init(side connSide, maxDatagramSize int, now time.Time) {
	c.side = side
	if side == clientSide {
		// Clients don't have an anti-amplification limit.
		c.antiAmplificationLimit = antiAmplificationUnlimited
	}
	c.rtt.init()
	c.cc = newReno(maxDatagramSize)
	c.pacer.init(now, c.cc.congestionWindow, timerGranularity)

	// Peer's assumed max_ack_delay, prior to receiving transport parameters.
	// https://www.rfc-editor.org/rfc/rfc9000#section-18.2
	c.maxAckDelay = 25 * time.Millisecond

	for space := range c.spaces {
		c.spaces[space].maxAcked = -1
		c.spaces[space].lastAckEliciting = -1
	}
}

// setMaxAckDelay sets the max_ack_delay transport parameter received from the peer.
func (c *lossState) setMaxAckDelay(d time.Duration) {
	if d >= (1<<14)*time.Millisecond {
		// Values of 2^14 or greater are invalid.
		// https://www.rfc-editor.org/rfc/rfc9000.html#section-18.2-4.28.1
		return
	}
	c.maxAckDelay = d
}

// confirmHandshake indicates the handshake has been confirmed.
func (c *lossState) confirmHandshake() {
	c.handshakeConfirmed = true
}

// validateClientAddress disables the anti-amplification limit after
// a server validates a client's address.
func (c *lossState) validateClientAddress() {
	c.antiAmplificationLimit = antiAmplificationUnlimited
}

// minDatagramSize is the minimum datagram size permitted by
// anti-amplification protection.
//
// Defining a minimum size avoids the case where, say, anti-amplification
// technically allows us to send a 1-byte datagram, but no such datagram
// can be constructed.
const minPacketSize = 128

type ccLimit int

const (
	ccOK      = ccLimit(iota) // OK to send
	ccBlocked                 // sending blocked by anti-amplification
	ccLimited                 // sending blocked by congestion control
	ccPaced                   // sending allowed by congestion, but delayed by pacer
)

// sendLimit reports whether sending is possible at this time.
// When sending is pacing limited, it returns the next time a packet may be sent.
func (c *lossState) sendLimit(now time.Time) (limit ccLimit, next time.Time) {
	if c.antiAmplificationLimit < minPacketSize {
		// When at the anti-amplification limit, we may not send anything.
		return ccBlocked, time.Time{}
	}
	if c.ptoExpired {
		// On PTO expiry, send a probe.
		return ccOK, time.Time{}
	}
	if !c.cc.canSend() {
		// Congestion control blocks sending.
		return ccLimited, time.Time{}
	}
	if c.cc.bytesInFlight == 0 {
		// If no bytes are in flight, send packet unpaced.
		return ccOK, time.Time{}
	}
	canSend, next := c.pacer.canSend(now)
	if !canSend {
		// Pacer blocks sending.
		return ccPaced, next
	}
	return ccOK, time.Time{}
}

// maxSendSize reports the maximum datagram size that may be sent.
func (c *lossState) maxSendSize() int {
	return min(c.antiAmplificationLimit, c.cc.maxDatagramSize)
}

// advance is called when time passes.
// The lossf function is called for each packet newly detected as lost.
func (c *lossState) advance(now time.Time, lossf func(numberSpace, *sentPacket, packetFate)) {
	c.pacer.advance(now, c.cc.congestionWindow, c.rtt.smoothedRTT)
	if c.ptoTimerArmed && !c.timer.IsZero() && !c.timer.After(now) {
		c.ptoExpired = true
		c.timer = time.Time{}
		c.ptoBackoffCount++
	}
	c.detectLoss(now, lossf)
}

// nextNumber returns the next packet number to use in a space.
func (c *lossState) nextNumber(space numberSpace) packetNumber {
	return c.spaces[space].nextNum
}

// packetSent records a sent packet.
func (c *lossState) packetSent(now time.Time, space numberSpace, sent *sentPacket) {
	sent.time = now
	c.spaces[space].add(sent)
	size := sent.size
	if c.antiAmplificationLimit != antiAmplificationUnlimited {
		c.antiAmplificationLimit = max(0, c.antiAmplificationLimit-size)
	}
	if sent.inFlight {
		c.cc.packetSent(now, space, sent)
		c.pacer.packetSent(now, size, c.cc.congestionWindow, c.rtt.smoothedRTT)
		if sent.ackEliciting {
			c.spaces[space].lastAckEliciting = sent.num
			c.ptoExpired = false // reset expired PTO timer after sending probe
		}
		c.scheduleTimer(now)
	}
	if sent.ackEliciting {
		c.consecutiveNonAckElicitingPackets = 0
	} else {
		c.consecutiveNonAckElicitingPackets++
	}
}

// datagramReceived records a datagram (not packet!) received from the peer.
func (c *lossState) datagramReceived(now time.Time, size int) {
	if c.antiAmplificationLimit != antiAmplificationUnlimited {
		c.antiAmplificationLimit += 3 * size
		// Reset the PTO timer, possibly to a point in the past, in which
		// case the caller should execute it immediately.
		// https://www.rfc-editor.org/rfc/rfc9002.html#section-6.2.2.1-2
		c.scheduleTimer(now)
		if c.ptoTimerArmed && !c.timer.IsZero() && !c.timer.After(now) {
			c.ptoExpired = true
			c.timer = time.Time{}
		}
	}
}

// receiveAckStart starts processing an ACK frame.
// Call receiveAckRange for each range in the frame.
// Call receiveAckFrameEnd after all ranges are processed.
func (c *lossState) receiveAckStart() {
	c.ackFrameContainsAckEliciting = false
	c.ackFrameRTT = -1
}

// receiveAckRange processes a range within an ACK frame.
// The ackf function is called for each newly-acknowledged packet.
func (c *lossState) receiveAckRange(now time.Time, space numberSpace, rangeIndex int, start, end packetNumber, ackf func(numberSpace, *sentPacket, packetFate)) {
	// Limit our range to the intersection of the ACK range and
	// the in-flight packets we have state for.
	if s := c.spaces[space].start(); start < s {
		start = s
	}
	if e := c.spaces[space].end(); end > e {
		end = e
	}
	if start >= end {
		return
	}
	if rangeIndex == 0 {
		// If the latest packet in the ACK frame is newly-acked,
		// record the RTT in c.ackFrameRTT.
		sent := c.spaces[space].num(end - 1)
		if !sent.acked {
			c.ackFrameRTT = max(0, now.Sub(sent.time))
		}
	}
	for pnum := start; pnum < end; pnum++ {
		sent := c.spaces[space].num(pnum)
		if sent.acked || sent.lost {
			continue
		}
		// This is a newly-acknowledged packet.
		if pnum > c.spaces[space].maxAcked {
			c.spaces[space].maxAcked = pnum
		}
		sent.acked = true
		c.cc.packetAcked(now, sent)
		ackf(space, sent, packetAcked)
		if sent.ackEliciting {
			c.ackFrameContainsAckEliciting = true
		}
	}
}

// receiveAckEnd finishes processing an ack frame.
// The lossf function is called for each packet newly detected as lost.
func (c *lossState) receiveAckEnd(now time.Time, space numberSpace, ackDelay time.Duration, lossf func(numberSpace, *sentPacket, packetFate)) {
	c.spaces[space].sentPacketList.clean()
	// Update the RTT sample when the largest acknowledged packet in the ACK frame
	// is newly acknowledged, and at least one newly acknowledged packet is ack-eliciting.
	// https://www.rfc-editor.org/rfc/rfc9002.html#section-5.1-2.2
	if c.ackFrameRTT >= 0 && c.ackFrameContainsAckEliciting {
		c.rtt.updateSample(now, c.handshakeConfirmed, space, c.ackFrameRTT, ackDelay, c.maxAckDelay)
	}
	// Reset the PTO backoff.
	// Exception: A client does not reset the backoff on acks for Initial packets.
	// https://www.rfc-editor.org/rfc/rfc9002.html#section-6.2.1-9
	if !(c.side == clientSide && space == initialSpace) {
		c.ptoBackoffCount = 0
	}
	// If the client has set a PTO timer with no packets in flight
	// we want to restart that timer now. Clearing c.timer does this.
	// https://www.rfc-editor.org/rfc/rfc9002.html#section-6.2.2.1-3
	c.timer = time.Time{}
	c.detectLoss(now, lossf)
	c.cc.packetBatchEnd(now, space, &c.rtt, c.maxAckDelay)
}

// discardPackets declares that packets within a number space will not be delivered
// and that data contained in them should be resent.
// For example, after receiving a Retry packet we discard already-sent Initial packets.
func (c *lossState) discardPackets(space numberSpace, lossf func(numberSpace, *sentPacket, packetFate)) {
	for i := 0; i < c.spaces[space].size; i++ {
		sent := c.spaces[space].nth(i)
		sent.lost = true
		c.cc.packetDiscarded(sent)
		lossf(numberSpace(space), sent, packetLost)
	}
	c.spaces[space].clean()
}

// discardKeys is called when dropping packet protection keys for a number space.
func (c *lossState) discardKeys(now time.Time, space numberSpace) {
	// https://www.rfc-editor.org/rfc/rfc9002.html#section-6.4
	for i := 0; i < c.spaces[space].size; i++ {
		sent := c.spaces[space].nth(i)
		c.cc.packetDiscarded(sent)
	}
	c.spaces[space].discard()
	c.spaces[space].maxAcked = -1
	c.spaces[space].lastAckEliciting = -1
	c.scheduleTimer(now)
}

func (c *lossState) lossDuration() time.Duration {
	// https://www.rfc-editor.org/rfc/rfc9002.html#section-6.1.2
	return max((9*max(c.rtt.smoothedRTT, c.rtt.latestRTT))/8, timerGranularity)
}

func (c *lossState) detectLoss(now time.Time, lossf func(numberSpace, *sentPacket, packetFate)) {
	// https://www.rfc-editor.org/rfc/rfc9002.html#section-6.1.1-1
	const lossThreshold = 3

	lossTime := now.Add(-c.lossDuration())
	for space := numberSpace(0); space < numberSpaceCount; space++ {
		for i := 0; i < c.spaces[space].size; i++ {
			sent := c.spaces[space].nth(i)
			if sent.lost || sent.acked {
				continue
			}
			// RFC 9002 Section 6.1 states that a packet is only declared lost if it
			// is "in flight", which excludes packets that contain only ACK frames.
			// However, we need some way to determine when to drop state for ACK-only
			// packets, and the loss algorithm in Appendix A handles loss detection of
			// not-in-flight packets identically to all others, so we do the same here.
			switch {
			case c.spaces[space].maxAcked-sent.num >= lossThreshold:
				// Packet threshold
				// https://www.rfc-editor.org/rfc/rfc9002.html#section-6.1.1
				fallthrough
			case sent.num <= c.spaces[space].maxAcked && !sent.time.After(lossTime):
				// Time threshold
				// https://www.rfc-editor.org/rfc/rfc9002.html#section-6.1.2
				sent.lost = true
				lossf(space, sent, packetLost)
				if sent.inFlight {
					c.cc.packetLost(now, space, sent, &c.rtt)
				}
			}
			if !sent.lost {
				break
			}
		}
		c.spaces[space].clean()
	}
	c.scheduleTimer(now)
}

// scheduleTimer sets the loss or PTO timer.
//
// The connection is responsible for arranging for advance to be called after
// the timer expires.
//
// The timer may be set to a point in the past, in which advance should be called
// immediately. We don't do this here, because executing the timer can cause
// packet loss events, and it's simpler for the connection if loss events only
// occur when advancing time.
func (c *lossState) scheduleTimer(now time.Time) {
	c.ptoTimerArmed = false

	// Loss timer for sent packets.
	// The loss timer is only started once a later packet has been acknowledged,
	// and takes precedence over the PTO timer.
	// https://www.rfc-editor.org/rfc/rfc9002.html#section-6.1.2
	var oldestPotentiallyLost time.Time
	for space := numberSpace(0); space < numberSpaceCount; space++ {
		if c.spaces[space].size > 0 && c.spaces[space].start() <= c.spaces[space].maxAcked {
			firstTime := c.spaces[space].nth(0).time
			if oldestPotentiallyLost.IsZero() || firstTime.Before(oldestPotentiallyLost) {
				oldestPotentiallyLost = firstTime
			}
		}
	}
	if !oldestPotentiallyLost.IsZero() {
		c.timer = oldestPotentiallyLost.Add(c.lossDuration())
		return
	}

	// PTO timer.
	if c.ptoExpired {
		// PTO timer has expired, don't restart it until we send a probe.
		c.timer = time.Time{}
		return
	}
	if c.antiAmplificationLimit >= 0 && c.antiAmplificationLimit < minPacketSize {
		// Server is at its anti-amplification limit and can't send any more data.
		// https://www.rfc-editor.org/rfc/rfc9002.html#section-6.2.2.1-1
		c.timer = time.Time{}
		return
	}
	// Timer starts at the most recently sent ack-eliciting packet.
	// Prior to confirming the handshake, we consider the Initial and Handshake
	// number spaces; after, we consider only Application Data.
	var last time.Time
	if !c.handshakeConfirmed {
		for space := initialSpace; space <= handshakeSpace; space++ {
			sent := c.spaces[space].num(c.spaces[space].lastAckEliciting)
			if sent == nil {
				continue
			}
			if last.IsZero() || last.After(sent.time) {
				last = sent.time
			}
		}
	} else {
		sent := c.spaces[appDataSpace].num(c.spaces[appDataSpace].lastAckEliciting)
		if sent != nil {
			last = sent.time
		}
	}
	if last.IsZero() &&
		c.side == clientSide &&
		c.spaces[handshakeSpace].maxAcked < 0 &&
		!c.handshakeConfirmed {
		// The client must always set a PTO timer prior to receiving an ack for a
		// handshake packet or the handshake being confirmed.
		// https://www.rfc-editor.org/rfc/rfc9002.html#section-6.2.2.1
		if !c.timer.IsZero() {
			// If c.timer is non-zero here, we've already set the PTO timer and
			// should leave it as-is rather than moving it forward.
			c.ptoTimerArmed = true
			return
		}
		last = now
	} else if last.IsZero() {
		c.timer = time.Time{}
		return
	}
	c.timer = last.Add(c.ptoPeriod())
	c.ptoTimerArmed = true
}

func (c *lossState) ptoPeriod() time.Duration {
	// https://www.rfc-editor.org/rfc/rfc9002.html#section-6.2.1
	return c.ptoBasePeriod() << c.ptoBackoffCount
}

func (c *lossState) ptoBasePeriod() time.Duration {
	// https://www.rfc-editor.org/rfc/rfc9002.html#section-6.2.1
	pto := c.rtt.smoothedRTT + max(4*c.rtt.rttvar, timerGranularity)
	if c.handshakeConfirmed {
		// The max_ack_delay is the maximum amount of time the peer might delay sending
		// an ack to us. We only take it into account for the Application Data space.
		// https://www.rfc-editor.org/rfc/rfc9002.html#section-6.2.1-4
		pto += c.maxAckDelay
	}
	return pto
}
