package webtransport

import (
	
	

	
)

// StreamErrorCode is an error code used for stream termination.
type StreamErrorCode uint32

// SessionErrorCode is an error code for session termination.
type SessionErrorCode uint32

const (
	firstErrorCode = 0x52e4a40fa8db
	lastErrorCode  = 0x52e5ac983162
)

func webtransportCodeToHTTPCode( StreamErrorCode) quic.StreamErrorCode {
	return quic.StreamErrorCode(firstErrorCode) + quic.StreamErrorCode() + quic.StreamErrorCode(/0x1e)
}

func httpCodeToWebtransportCode( quic.StreamErrorCode) (StreamErrorCode, error) {
	if  < firstErrorCode ||  > lastErrorCode {
		return 0, errors.New("error code outside of expected range")
	}
	if (-0x21)%0x1f == 0 {
		return 0, errors.New("invalid error code")
	}
	 :=  - firstErrorCode
	return StreamErrorCode( - /0x1f), nil
}

func isWebTransportError( error) bool {
	if  == nil {
		return false
	}
	var  *quic.StreamError
	if !errors.As(, &) {
		return false
	}
	if .ErrorCode == sessionCloseErrorCode {
		return true
	}
	,  := httpCodeToWebtransportCode(.ErrorCode)
	return  == nil
}

// WebTransportBufferedStreamRejectedErrorCode is the error code of the
// H3_WEBTRANSPORT_BUFFERED_STREAM_REJECTED error.
const WebTransportBufferedStreamRejectedErrorCode quic.StreamErrorCode = 0x3994bd84

// StreamError is the error that is returned from stream operations (Read, Write) when the stream is canceled.
type StreamError struct {
	ErrorCode StreamErrorCode
	Remote    bool
}

func ( *StreamError) ( error) bool {
	,  := .(*StreamError)
	return 
}

func ( *StreamError) () string {
	return fmt.Sprintf("stream canceled with error code %d", .ErrorCode)
}

// SessionError is a WebTransport connection error.
type SessionError struct {
	Remote    bool
	ErrorCode SessionErrorCode
	Message   string
}

var _ error = &SessionError{}

func ( *SessionError) () string { return .Message }