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

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

package webrtc

import (
	
	
	
	

	
	
)

// srtpWriterFuture blocks Read/Write calls until
// the SRTP Session is available.
type srtpWriterFuture struct {
	ssrc           SSRC
	rtpSender      *RTPSender
	rtcpReadStream atomic.Value // *srtp.ReadStreamSRTCP
	rtpWriteStream atomic.Value // *srtp.WriteStreamSRTP
	mu             sync.Mutex
	closed         bool
}

func ( *srtpWriterFuture) ( bool) error { //nolint:cyclop
	if  {
		select {
		case <-.rtpSender.stopCalled:
			return io.ErrClosedPipe
		case <-.rtpSender.transport.srtpReady:
		default:
			return nil
		}
	} else {
		select {
		case <-.rtpSender.stopCalled:
			return io.ErrClosedPipe
		case <-.rtpSender.transport.srtpReady:
		}
	}

	.mu.Lock()
	defer .mu.Unlock()

	if .closed {
		return io.ErrClosedPipe
	}

	,  := .rtpSender.transport.getSRTCPSession()
	if  != nil {
		return 
	}

	,  := .OpenReadStream(uint32(.ssrc))
	if  != nil {
		return 
	}

	,  := .rtpSender.transport.getSRTPSession()
	if  != nil {
		return 
	}

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

	.rtcpReadStream.Store()
	.rtpWriteStream.Store()

	return nil
}

func ( *srtpWriterFuture) () error {
	.mu.Lock()
	defer .mu.Unlock()

	if .closed {
		return nil
	}
	.closed = true

	if ,  := .rtcpReadStream.Load().(*srtp.ReadStreamSRTCP);  {
		return .Close()
	}

	return nil
}

func ( *srtpWriterFuture) ( []byte) ( int,  error) {
	if ,  := .rtcpReadStream.Load().(*srtp.ReadStreamSRTCP);  {
		return .Read()
	}

	if  := .init(false);  != nil || .rtcpReadStream.Load() == nil {
		return 0, 
	}

	return .()
}

func ( *srtpWriterFuture) ( time.Time) error {
	if ,  := .rtcpReadStream.Load().(*srtp.ReadStreamSRTCP);  {
		return .SetReadDeadline()
	}

	if  := .init(false);  != nil || .rtcpReadStream.Load() == nil {
		return 
	}

	return .()
}

func ( *srtpWriterFuture) ( *rtp.Header,  []byte) (int, error) {
	if ,  := .rtpWriteStream.Load().(*srtp.WriteStreamSRTP);  {
		return .WriteRTP(, )
	}

	if  := .init(true);  != nil || .rtpWriteStream.Load() == nil {
		return 0, 
	}

	return .(, )
}

func ( *srtpWriterFuture) ( []byte) (int, error) {
	if ,  := .rtpWriteStream.Load().(*srtp.WriteStreamSRTP);  {
		return .Write()
	}

	if  := .init(true);  != nil || .rtpWriteStream.Load() == nil {
		return 0, 
	}

	return .()
}