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

//go:build !js
// +build !js

package webrtc

import (
	

	
	
	
	
	
	
	
	
)

// RegisterDefaultInterceptors will register some useful interceptors.
// If you want to customize which interceptors are loaded, you should copy the
// code from this method and remove unwanted interceptors.
func ( *MediaEngine,  *interceptor.Registry) error {
	if  := ConfigureNack(, );  != nil {
		return 
	}

	if  := ConfigureRTCPReports();  != nil {
		return 
	}

	if  := ConfigureSimulcastExtensionHeaders();  != nil {
		return 
	}

	return ConfigureTWCCSender(, )
}

// ConfigureRTCPReports will setup everything necessary for generating Sender and Receiver Reports.
func ( *interceptor.Registry) error {
	,  := report.NewReceiverInterceptor()
	if  != nil {
		return 
	}

	,  := report.NewSenderInterceptor()
	if  != nil {
		return 
	}

	.Add()
	.Add()

	return nil
}

// ConfigureNack will setup everything necessary for handling generating/responding to nack messages.
func ( *MediaEngine,  *interceptor.Registry) error {
	,  := nack.NewGeneratorInterceptor()
	if  != nil {
		return 
	}

	,  := nack.NewResponderInterceptor()
	if  != nil {
		return 
	}

	.RegisterFeedback(RTCPFeedback{Type: "nack"}, RTPCodecTypeVideo)
	.RegisterFeedback(RTCPFeedback{Type: "nack", Parameter: "pli"}, RTPCodecTypeVideo)
	.Add()
	.Add()

	return nil
}

// ConfigureTWCCHeaderExtensionSender will setup everything necessary for adding
// a TWCC header extension to outgoing RTP packets. This will allow the remote peer to generate TWCC reports.
func ( *MediaEngine,  *interceptor.Registry) error {
	if  := .RegisterHeaderExtension(
		RTPHeaderExtensionCapability{URI: sdp.TransportCCURI}, RTPCodecTypeVideo,
	);  != nil {
		return 
	}

	if  := .RegisterHeaderExtension(
		RTPHeaderExtensionCapability{URI: sdp.TransportCCURI}, RTPCodecTypeAudio,
	);  != nil {
		return 
	}

	,  := twcc.NewHeaderExtensionInterceptor()
	if  != nil {
		return 
	}

	.Add()

	return nil
}

// ConfigureTWCCSender will setup everything necessary for generating TWCC reports.
// This must be called after registering codecs with the MediaEngine.
func ( *MediaEngine,  *interceptor.Registry) error {
	.RegisterFeedback(RTCPFeedback{Type: TypeRTCPFBTransportCC}, RTPCodecTypeVideo)
	if  := .RegisterHeaderExtension(
		RTPHeaderExtensionCapability{URI: sdp.TransportCCURI}, RTPCodecTypeVideo,
	);  != nil {
		return 
	}

	.RegisterFeedback(RTCPFeedback{Type: TypeRTCPFBTransportCC}, RTPCodecTypeAudio)
	if  := .RegisterHeaderExtension(
		RTPHeaderExtensionCapability{URI: sdp.TransportCCURI}, RTPCodecTypeAudio,
	);  != nil {
		return 
	}

	,  := twcc.NewSenderInterceptor()
	if  != nil {
		return 
	}

	.Add()

	return nil
}

// ConfigureCongestionControlFeedback registers congestion control feedback as
// defined in RFC 8888 (https://datatracker.ietf.org/doc/rfc8888/)
func ( *MediaEngine,  *interceptor.Registry) error {
	.RegisterFeedback(RTCPFeedback{Type: TypeRTCPFBACK, Parameter: "ccfb"}, RTPCodecTypeVideo)
	.RegisterFeedback(RTCPFeedback{Type: TypeRTCPFBACK, Parameter: "ccfb"}, RTPCodecTypeAudio)
	,  := rfc8888.NewSenderInterceptor()
	if  != nil {
		return 
	}
	.Add()

	return nil
}

// ConfigureSimulcastExtensionHeaders enables the RTP Extension Headers needed for Simulcast.
func ( *MediaEngine) error {
	if  := .RegisterHeaderExtension(
		RTPHeaderExtensionCapability{URI: sdp.SDESMidURI}, RTPCodecTypeVideo,
	);  != nil {
		return 
	}

	if  := .RegisterHeaderExtension(
		RTPHeaderExtensionCapability{URI: sdp.SDESRTPStreamIDURI}, RTPCodecTypeVideo,
	);  != nil {
		return 
	}

	return .RegisterHeaderExtension(
		RTPHeaderExtensionCapability{URI: sdp.SDESRepairRTPStreamIDURI}, RTPCodecTypeVideo,
	)
}

// ConfigureFlexFEC03 registers flexfec-03 codec with provided payloadType in mediaEngine
// and adds corresponding interceptor to the registry.
// Note that this function should be called before any other interceptor that modifies RTP packets
// (i.e. TWCCHeaderExtensionSender) is added to the registry, so that packets generated by flexfec
// interceptor are not modified.
func (
	 PayloadType,
	 *MediaEngine,
	 *interceptor.Registry,
	 ...flexfec.FecOption,
) error {
	 := RTPCodecParameters{
		RTPCodecCapability: RTPCodecCapability{
			MimeType:     MimeTypeFlexFEC03,
			ClockRate:    90000,
			SDPFmtpLine:  "repair-window=10000000",
			RTCPFeedback: nil,
		},
		PayloadType: ,
	}

	if  := .RegisterCodec(, RTPCodecTypeVideo);  != nil {
		return 
	}

	,  := flexfec.NewFecInterceptor(...)
	if  != nil {
		return 
	}

	.Add()

	return nil
}

type interceptorToTrackLocalWriter struct{ interceptor atomic.Value } // interceptor.RTPWriter }

func ( *interceptorToTrackLocalWriter) ( *rtp.Header,  []byte) (int, error) {
	if ,  := .interceptor.Load().(interceptor.RTPWriter);  &&  != nil {
		return .Write(, , interceptor.Attributes{})
	}

	return 0, nil
}

func ( *interceptorToTrackLocalWriter) ( []byte) (int, error) {
	 := &rtp.Packet{}
	if  := .Unmarshal();  != nil {
		return 0, 
	}

	return .WriteRTP(&.Header, .Payload)
}

//nolint:unparam
func createStreamInfo(
	 string,
	, ,  SSRC,
	, ,  PayloadType,
	 RTPCodecCapability,
	 []RTPHeaderExtensionParameter,
) *interceptor.StreamInfo {
	 := make([]interceptor.RTPHeaderExtension, 0, len())
	for ,  := range  {
		 = append(, interceptor.RTPHeaderExtension{ID: .ID, URI: .URI})
	}

	 := make([]interceptor.RTCPFeedback, 0, len(.RTCPFeedback))
	for ,  := range .RTCPFeedback {
		 = append(, interceptor.RTCPFeedback{Type: .Type, Parameter: .Parameter})
	}

	return &interceptor.StreamInfo{
		ID:                                ,
		Attributes:                        interceptor.Attributes{},
		SSRC:                              uint32(),
		SSRCRetransmission:                uint32(),
		SSRCForwardErrorCorrection:        uint32(),
		PayloadType:                       uint8(),
		PayloadTypeRetransmission:         uint8(),
		PayloadTypeForwardErrorCorrection: uint8(),
		RTPHeaderExtensions:               ,
		MimeType:                          .MimeType,
		ClockRate:                         .ClockRate,
		Channels:                          .Channels,
		SDPFmtpLine:                       .SDPFmtpLine,
		RTCPFeedback:                      ,
	}
}