package libp2pquic

import (
	

	ic 
	
	
	tpt 

	ma 
	
)

type conn struct {
	quicConn  quic.Connection
	transport *transport
	scope     network.ConnManagementScope

	localPeer      peer.ID
	localMultiaddr ma.Multiaddr

	remotePeerID    peer.ID
	remotePubKey    ic.PubKey
	remoteMultiaddr ma.Multiaddr
}

var _ tpt.CapableConn = &conn{}

// Close closes the connection.
// It must be called even if the peer closed the connection in order for
// garbage collection to properly work in this package.
func ( *conn) () error {
	return .closeWithError(0, "")
}

// CloseWithError closes the connection
// It must be called even if the peer closed the connection in order for
// garbage collection to properly work in this package.
func ( *conn) ( network.ConnErrorCode) error {
	return .closeWithError(quic.ApplicationErrorCode(), "")
}

func ( *conn) ( quic.ApplicationErrorCode,  string) error {
	.transport.removeConn(.quicConn)
	 := .quicConn.CloseWithError(, )
	.scope.Done()
	return 
}

// IsClosed returns whether a connection is fully closed.
func ( *conn) () bool {
	return .quicConn.Context().Err() != nil
}

func ( *conn) ( uint64) bool {
	return .scope.ReserveMemory(int(), network.ReservationPriorityMedium) == nil
}

// OpenStream creates a new stream.
func ( *conn) ( context.Context) (network.MuxedStream, error) {
	,  := .quicConn.OpenStreamSync()
	if  != nil {
		return nil, parseStreamError()
	}
	return &stream{Stream: }, nil
}

// AcceptStream accepts a stream opened by the other side.
func ( *conn) () (network.MuxedStream, error) {
	,  := .quicConn.AcceptStream(context.Background())
	if  != nil {
		return nil, parseStreamError()
	}
	return &stream{Stream: }, nil
}

// LocalPeer returns our peer ID
func ( *conn) () peer.ID { return .localPeer }

// RemotePeer returns the peer ID of the remote peer.
func ( *conn) () peer.ID { return .remotePeerID }

// RemotePublicKey returns the public key of the remote peer.
func ( *conn) () ic.PubKey { return .remotePubKey }

// LocalMultiaddr returns the local Multiaddr associated
func ( *conn) () ma.Multiaddr { return .localMultiaddr }

// RemoteMultiaddr returns the remote Multiaddr associated
func ( *conn) () ma.Multiaddr { return .remoteMultiaddr }

func ( *conn) () tpt.Transport { return .transport }

func ( *conn) () network.ConnScope { return .scope }

// ConnState is the state of security connection.
func ( *conn) () network.ConnectionState {
	 := "quic-v1"
	if ,  := .LocalMultiaddr().ValueForProtocol(ma.P_QUIC);  == nil {
		 = "quic"
	}
	return network.ConnectionState{Transport: }
}