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

// handleAckOrLoss deals with the final fate of a packet we sent:
// Either the peer acknowledges it, or we declare it lost.
//
// In order to handle packet loss, we must retain any information sent to the peer
// until the peer has acknowledged it.
//
// When information is acknowledged, we can discard it.
//
// When information is lost, we mark it for retransmission.
// See RFC 9000, Section 13.3 for a complete list of information which is retransmitted on loss.
// https://www.rfc-editor.org/rfc/rfc9000#section-13.3
func (c *Conn) handleAckOrLoss(space numberSpace, sent *sentPacket, fate packetFate) {
	if fate == packetLost && c.logEnabled(QLogLevelPacket) {
		c.logPacketLost(space, sent)
	}

	// The list of frames in a sent packet is marshaled into a buffer in the sentPacket
	// by the packetWriter. Unmarshal that buffer here. This code must be kept in sync with
	// packetWriter.append*.
	//
	// A sent packet meets its fate (acked or lost) only once, so it's okay to consume
	// the sentPacket's buffer here.
	for !sent.done() {
		switch f := sent.next(); f {
		default:
			panic(fmt.Sprintf("BUG: unhandled acked/lost frame type %x", f))
		case frameTypeAck:
			// Unlike most information, loss of an ACK frame does not trigger
			// retransmission. ACKs are sent in response to ack-eliciting packets,
			// and always contain the latest information available.
			//
			// Acknowledgement of an ACK frame may allow us to discard information
			// about older packets.
			largest := packetNumber(sent.nextInt())
			if fate == packetAcked {
				c.acks[space].handleAck(largest)
			}
		case frameTypeCrypto:
			start, end := sent.nextRange()
			c.crypto[space].ackOrLoss(start, end, fate)
		case frameTypeMaxData:
			c.ackOrLossMaxData(sent.num, fate)
		case frameTypeResetStream,
			frameTypeStopSending,
			frameTypeMaxStreamData,
			frameTypeStreamDataBlocked:
			id := streamID(sent.nextInt())
			s := c.streamForID(id)
			if s == nil {
				continue
			}
			s.ackOrLoss(sent.num, f, fate)
		case frameTypeStreamBase,
			frameTypeStreamBase | streamFinBit:
			id := streamID(sent.nextInt())
			start, end := sent.nextRange()
			s := c.streamForID(id)
			if s == nil {
				continue
			}
			fin := f&streamFinBit != 0
			s.ackOrLossData(sent.num, start, end, fin, fate)
		case frameTypeMaxStreamsBidi:
			c.streams.remoteLimit[bidiStream].sendMax.ackLatestOrLoss(sent.num, fate)
		case frameTypeMaxStreamsUni:
			c.streams.remoteLimit[uniStream].sendMax.ackLatestOrLoss(sent.num, fate)
		case frameTypeNewConnectionID:
			seq := int64(sent.nextInt())
			c.connIDState.ackOrLossNewConnectionID(sent.num, seq, fate)
		case frameTypeRetireConnectionID:
			seq := int64(sent.nextInt())
			c.connIDState.ackOrLossRetireConnectionID(sent.num, seq, fate)
		case frameTypeHandshakeDone:
			c.handshakeConfirmed.ackOrLoss(sent.num, fate)
		}
	}
}
