package quic

import (
	
	
	
	
	

	
	
	
	
	
)

type deadlineError struct{}

func (deadlineError) () string   { return "deadline exceeded" }
func (deadlineError) () bool { return true }
func (deadlineError) () bool   { return true }
func (deadlineError) () error   { return os.ErrDeadlineExceeded }

var errDeadline net.Error = &deadlineError{}

// The streamSender is notified by the stream about various events.
type streamSender interface {
	onHasConnectionData()
	onHasStreamData(protocol.StreamID, *SendStream)
	onHasStreamControlFrame(protocol.StreamID, streamControlFrameGetter)
	// must be called without holding the mutex that is acquired by closeForShutdown
	onStreamCompleted(protocol.StreamID)
}

// Each of the both stream halves gets its own uniStreamSender.
// This is necessary in order to keep track when both halves have been completed.
type uniStreamSender struct {
	streamSender
	onStreamCompletedImpl       func()
	onHasStreamControlFrameImpl func(protocol.StreamID, streamControlFrameGetter)
}

func ( *uniStreamSender) ( protocol.StreamID,  *SendStream) {
	.streamSender.onHasStreamData(, )
}
func ( *uniStreamSender) (protocol.StreamID) { .onStreamCompletedImpl() }
func ( *uniStreamSender) ( protocol.StreamID,  streamControlFrameGetter) {
	.onHasStreamControlFrameImpl(, )
}

var _ streamSender = &uniStreamSender{}

type Stream struct {
	receiveStr *ReceiveStream
	sendStr    *SendStream

	completedMutex         sync.Mutex
	sender                 streamSender
	receiveStreamCompleted bool
	sendStreamCompleted    bool
}

var (
	_ outgoingStream            = &Stream{}
	_ sendStreamFrameHandler    = &Stream{}
	_ receiveStreamFrameHandler = &Stream{}
)

// newStream creates a new Stream
func newStream(
	 context.Context,
	 protocol.StreamID,
	 streamSender,
	 flowcontrol.StreamFlowController,
	 bool,
) *Stream {
	 := &Stream{sender: }
	 := &uniStreamSender{
		streamSender: ,
		onStreamCompletedImpl: func() {
			.completedMutex.Lock()
			.sendStreamCompleted = true
			.checkIfCompleted()
			.completedMutex.Unlock()
		},
		onHasStreamControlFrameImpl: func( protocol.StreamID,  streamControlFrameGetter) {
			.onHasStreamControlFrame(, )
		},
	}
	.sendStr = newSendStream(, , , , )
	 := &uniStreamSender{
		streamSender: ,
		onStreamCompletedImpl: func() {
			.completedMutex.Lock()
			.receiveStreamCompleted = true
			.checkIfCompleted()
			.completedMutex.Unlock()
		},
		onHasStreamControlFrameImpl: func( protocol.StreamID,  streamControlFrameGetter) {
			.onHasStreamControlFrame(, )
		},
	}
	.receiveStr = newReceiveStream(, , )
	return 
}

// StreamID returns the stream ID.
func ( *Stream) () protocol.StreamID {
	// the result is same for receiveStream and sendStream
	return .sendStr.StreamID()
}

// Read reads data from the stream.
// Read can be made to time out using [Stream.SetReadDeadline] and [Stream.SetDeadline].
// If the stream was canceled, the error is a [StreamError].
func ( *Stream) ( []byte) (int, error) {
	return .receiveStr.Read()
}

// Peek fills b with stream data, without consuming the stream data.
// It blocks until len(b) bytes are available, or an error occurs.
// It respects the stream deadline set by SetReadDeadline.
// If the stream ends before len(b) bytes are available,
// it returns the number of bytes peeked along with io.EOF.
func ( *Stream) ( []byte) (int, error) {
	return .receiveStr.Peek()
}

// Write writes data to the stream.
// Write can be made to time out using [Stream.SetWriteDeadline] or [Stream.SetDeadline].
// If the stream was canceled, the error is a [StreamError].
func ( *Stream) ( []byte) (int, error) {
	return .sendStr.Write()
}

// SetReliableBoundary marks the data written to this stream so far as reliable.
// It is valid to call this function multiple times, thereby increasing the reliable size.
// It only has an effect if the peer enabled support for the RESET_STREAM_AT extension,
// otherwise, it is a no-op.
func ( *Stream) () {
	.sendStr.SetReliableBoundary()
}

// CancelWrite aborts sending on this stream.
// See [SendStream.CancelWrite] for more details.
func ( *Stream) ( StreamErrorCode) {
	.sendStr.CancelWrite()
}

// CancelRead aborts receiving on this stream.
// See [ReceiveStream.CancelRead] for more details.
func ( *Stream) ( StreamErrorCode) {
	.receiveStr.CancelRead()
}

// The Context is canceled as soon as the write-side of the stream is closed.
// See [SendStream.Context] for more details.
func ( *Stream) () context.Context {
	return .sendStr.Context()
}

// Close closes the send-direction of the stream.
// It does not close the receive-direction of the stream.
func ( *Stream) () error {
	return .sendStr.Close()
}

func ( *Stream) ( *wire.ResetStreamFrame,  monotime.Time) error {
	return .receiveStr.handleResetStreamFrame(, )
}

func ( *Stream) ( *wire.StreamFrame,  monotime.Time) error {
	return .receiveStr.handleStreamFrame(, )
}

func ( *Stream) ( *wire.StopSendingFrame) {
	.sendStr.handleStopSendingFrame()
}

func ( *Stream) ( protocol.ByteCount) {
	.sendStr.updateSendWindow()
}

func ( *Stream) () {
	.sendStr.enableResetStreamAt()
}

func ( *Stream) ( protocol.ByteCount,  protocol.Version) ( ackhandler.StreamFrame,  *wire.StreamDataBlockedFrame,  bool) {
	return .sendStr.popStreamFrame(, )
}

func ( *Stream) ( monotime.Time) ( ackhandler.Frame, ,  bool) {
	, ,  := .sendStr.getControlFrame()
	if  {
		return , true, true
	}
	return .receiveStr.getControlFrame()
}

// SetReadDeadline sets the deadline for future Read calls.
// See [ReceiveStream.SetReadDeadline] for more details.
func ( *Stream) ( time.Time) error {
	return .receiveStr.SetReadDeadline()
}

// SetWriteDeadline sets the deadline for future Write calls.
// See [SendStream.SetWriteDeadline] for more details.
func ( *Stream) ( time.Time) error {
	return .sendStr.SetWriteDeadline()
}

// SetDeadline sets the read and write deadlines associated with the stream.
// It is equivalent to calling both SetReadDeadline and SetWriteDeadline.
func ( *Stream) ( time.Time) error {
	_ = .receiveStr.SetReadDeadline() // SetReadDeadline never errors
	_ = .sendStr.SetWriteDeadline()   // SetWriteDeadline never errors
	return nil
}

// CloseForShutdown closes a stream abruptly.
// It makes Read and Write unblock (and return the error) immediately.
// The peer will NOT be informed about this: the stream is closed without sending a FIN or RST.
func ( *Stream) ( error) {
	.sendStr.closeForShutdown()
	.receiveStr.closeForShutdown()
}

// checkIfCompleted is called from the uniStreamSender, when one of the stream halves is completed.
// It makes sure that the onStreamCompleted callback is only called if both receive and send side have completed.
func ( *Stream) () {
	if .sendStreamCompleted && .receiveStreamCompleted {
		.sender.onStreamCompleted(.StreamID())
	}
}