// 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

	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)
	}
}

// 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)
}

// 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
	}
	// https://www.rfc-editor.org/rfc/rfc9002.html#section-6.2.1
	pto := c.ptoBasePeriod() << c.ptoBackoffCount
	c.timer = last.Add(pto)
	c.ptoTimerArmed = true
}

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
}
