package ackhandler

import (
	

	
	
	
	
)

type ReceivedPacketHandler struct {
	initialPackets   *receivedPacketTracker
	handshakePackets *receivedPacketTracker
	appDataPackets   appDataReceivedPacketTracker

	lowest1RTTPacket protocol.PacketNumber
}

func ( utils.Logger) *ReceivedPacketHandler {
	return &ReceivedPacketHandler{
		initialPackets:   newReceivedPacketTracker(),
		handshakePackets: newReceivedPacketTracker(),
		appDataPackets:   *newAppDataReceivedPacketTracker(),
		lowest1RTTPacket: protocol.InvalidPacketNumber,
	}
}

func ( *ReceivedPacketHandler) (
	 protocol.PacketNumber,
	 protocol.ECN,
	 protocol.EncryptionLevel,
	 monotime.Time,
	 bool,
) error {
	switch  {
	case protocol.EncryptionInitial:
		return .initialPackets.ReceivedPacket(, , )
	case protocol.EncryptionHandshake:
		// The Handshake packet number space might already have been dropped as a result
		// of processing the CRYPTO frame that was contained in this packet.
		if .handshakePackets == nil {
			return nil
		}
		return .handshakePackets.ReceivedPacket(, , )
	case protocol.Encryption0RTT:
		if .lowest1RTTPacket != protocol.InvalidPacketNumber &&  > .lowest1RTTPacket {
			return fmt.Errorf("received packet number %d on a 0-RTT packet after receiving %d on a 1-RTT packet", , .lowest1RTTPacket)
		}
		return .appDataPackets.ReceivedPacket(, , , )
	case protocol.Encryption1RTT:
		if .lowest1RTTPacket == protocol.InvalidPacketNumber ||  < .lowest1RTTPacket {
			.lowest1RTTPacket = 
		}
		return .appDataPackets.ReceivedPacket(, , , )
	default:
		panic(fmt.Sprintf("received packet with unknown encryption level: %s", ))
	}
}

func ( *ReceivedPacketHandler) ( protocol.PacketNumber) {
	.appDataPackets.IgnoreBelow()
}

func ( *ReceivedPacketHandler) ( protocol.EncryptionLevel) {
	//nolint:exhaustive // 1-RTT packet number space is never dropped.
	switch  {
	case protocol.EncryptionInitial:
		.initialPackets = nil
	case protocol.EncryptionHandshake:
		.handshakePackets = nil
	case protocol.Encryption0RTT:
		// Nothing to do here.
		// If we are rejecting 0-RTT, no 0-RTT packets will have been decrypted.
	default:
		panic(fmt.Sprintf("Cannot drop keys for encryption level %s", ))
	}
}

func ( *ReceivedPacketHandler) () monotime.Time {
	return .appDataPackets.GetAlarmTimeout()
}

func ( *ReceivedPacketHandler) ( protocol.EncryptionLevel,  monotime.Time,  bool) *wire.AckFrame {
	//nolint:exhaustive // 0-RTT packets can't contain ACK frames.
	switch  {
	case protocol.EncryptionInitial:
		if .initialPackets != nil {
			return .initialPackets.GetAckFrame()
		}
		return nil
	case protocol.EncryptionHandshake:
		if .handshakePackets != nil {
			return .handshakePackets.GetAckFrame()
		}
		return nil
	case protocol.Encryption1RTT:
		return .appDataPackets.GetAckFrame(, )
	default:
		// 0-RTT packets can't contain ACK frames
		return nil
	}
}

func ( *ReceivedPacketHandler) ( protocol.PacketNumber,  protocol.EncryptionLevel) bool {
	switch  {
	case protocol.EncryptionInitial:
		if .initialPackets != nil {
			return .initialPackets.IsPotentiallyDuplicate()
		}
	case protocol.EncryptionHandshake:
		if .handshakePackets != nil {
			return .handshakePackets.IsPotentiallyDuplicate()
		}
	case protocol.Encryption0RTT, protocol.Encryption1RTT:
		return .appDataPackets.IsPotentiallyDuplicate()
	}
	panic("unexpected encryption level")
}