// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
// SPDX-License-Identifier: MIT

package rtp

import (
	
)

// Payloader payloads a byte array for use as rtp.Packet payloads.
type Payloader interface {
	Payload(mtu uint16, payload []byte) [][]byte
}

// Packetizer packetizes a payload.
type Packetizer interface {
	Packetize(payload []byte, samples uint32) []*Packet
	GeneratePadding(samples uint32) []*Packet
	EnableAbsSendTime(value int)
	SkipSamples(skippedSamples uint32)
}

type packetizer struct {
	MTU         uint16
	PayloadType uint8
	SSRC        uint32
	Payloader   Payloader
	Sequencer   Sequencer
	Timestamp   uint32

	// Deprecated: will be removed in a future version.
	ClockRate uint32

	// put extension numbers in here. If they're 0, the extension is disabled (0 is not a legal extension number)
	extensionNumbers struct {
		AbsSendTime int // http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
	}
	timegen func() time.Time
}

// NewPacketizer returns a new instance of a Packetizer for a specific payloader.
func (
	 uint16,
	 uint8,
	 uint32,
	 Payloader,
	 Sequencer,
	 uint32,
) Packetizer {
	return &packetizer{
		MTU:         ,
		PayloadType: ,
		SSRC:        ,
		Payloader:   ,
		Sequencer:   ,
		Timestamp:   globalMathRandomGenerator.Uint32(),
		ClockRate:   ,
		timegen:     time.Now,
	}
}

// WithSSRC sets the SSRC for the Packetizer.
func ( uint32) func(*packetizer) {
	return func( *packetizer) {
		.SSRC = 
	}
}

// WithPayloadType sets the PayloadType for the Packetizer.
func ( uint8) func(*packetizer) {
	return func( *packetizer) {
		.PayloadType = 
	}
}

// WithTimestamp sets the initial Timestamp for the Packetizer.
func ( uint32) func(*packetizer) {
	return func( *packetizer) {
		.Timestamp = 
	}
}

// PacketizerOption is a function that configures a RTP Packetizer.
type PacketizerOption func(*packetizer)

// NewPacketizerWithOptions returns a new instance of a Packetizer with the given options.
func (
	 uint16,
	 Payloader,
	 Sequencer,
	 uint32,
	 ...PacketizerOption,
) Packetizer {
	 := &packetizer{
		MTU:       ,
		Payloader: ,
		Sequencer: ,
		Timestamp: globalMathRandomGenerator.Uint32(),
		ClockRate: ,
		timegen:   time.Now,
	}

	for ,  := range  {
		()
	}

	return 
}

func ( *packetizer) ( int) {
	.extensionNumbers.AbsSendTime = 
}

// Packetize packetizes the payload of an RTP packet and returns one or more RTP packets.
func ( *packetizer) ( []byte,  uint32) []*Packet {
	// Guard against an empty payload
	if len() == 0 {
		return nil
	}

	 := .Payloader.Payload(.MTU-12, )
	 := make([]*Packet, len())

	for ,  := range  {
		[] = &Packet{
			Header: Header{
				Version:        2,
				Padding:        false,
				Extension:      false,
				Marker:          == len()-1,
				PayloadType:    .PayloadType,
				SequenceNumber: .Sequencer.NextSequenceNumber(),
				Timestamp:      .Timestamp, // Figure out how to do timestamps
				SSRC:           .SSRC,
				CSRC:           []uint32{},
			},
			Payload: ,
		}
	}
	.Timestamp += 

	if len() != 0 && .extensionNumbers.AbsSendTime != 0 {
		 := NewAbsSendTimeExtension(.timegen())
		// apply http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
		,  := .Marshal()
		if  != nil {
			return nil // never happens
		}
		 = [len()-1].SetExtension(uint8(.extensionNumbers.AbsSendTime), ) // nolint: gosec // G115
		if  != nil {
			return nil // never happens
		}
	}

	return 
}

// GeneratePadding returns required padding-only packages.
func ( *packetizer) ( uint32) []*Packet {
	// Guard against an empty payload
	if  == 0 {
		return nil
	}

	 := make([]*Packet, )

	for  := 0;  < int(); ++ {
		[] = &Packet{
			Header: Header{
				Version:        2,
				Padding:        true,
				Extension:      false,
				Marker:         false,
				PayloadType:    .PayloadType,
				SequenceNumber: .Sequencer.NextSequenceNumber(),
				Timestamp:      .Timestamp, // Use latest timestamp
				SSRC:           .SSRC,
				CSRC:           []uint32{},
				PaddingSize:    255,
			},
		}
	}

	return 
}

// SkipSamples causes a gap in sample count between Packetize requests so the
// RTP payloads produced have a gap in timestamps.
func ( *packetizer) ( uint32) {
	.Timestamp += 
}