package network

import (
	
	
)

// DialPeerTimeout is the default timeout for a single call to `DialPeer`. When
// there are multiple concurrent calls to `DialPeer`, this timeout will apply to
// each independently.
var DialPeerTimeout = 60 * time.Second

type noDialCtxKey struct{}
type dialPeerTimeoutCtxKey struct{}
type forceDirectDialCtxKey struct{}
type allowLimitedConnCtxKey struct{}
type simConnectCtxKey struct{ isClient bool }

var noDial = noDialCtxKey{}
var forceDirectDial = forceDirectDialCtxKey{}
var allowLimitedConn = allowLimitedConnCtxKey{}
var simConnectIsServer = simConnectCtxKey{}
var simConnectIsClient = simConnectCtxKey{isClient: true}

// EXPERIMENTAL
// WithForceDirectDial constructs a new context with an option that instructs the network
// to attempt to force a direct connection to a peer via a dial even if a proxied connection to it already exists.
func ( context.Context,  string) context.Context {
	return context.WithValue(, forceDirectDial, )
}

// EXPERIMENTAL
// GetForceDirectDial returns true if the force direct dial option is set in the context.
func ( context.Context) ( bool,  string) {
	 := .Value(forceDirectDial)
	if  != nil {
		return true, .(string)
	}

	return false, ""
}

// WithSimultaneousConnect constructs a new context with an option that instructs the transport
// to apply hole punching logic where applicable.
// EXPERIMENTAL
func ( context.Context,  bool,  string) context.Context {
	if  {
		return context.WithValue(, simConnectIsClient, )
	}
	return context.WithValue(, simConnectIsServer, )
}

// GetSimultaneousConnect returns true if the simultaneous connect option is set in the context.
// EXPERIMENTAL
func ( context.Context) ( bool,  bool,  string) {
	if  := .Value(simConnectIsClient);  != nil {
		return true, true, .(string)
	}
	if  := .Value(simConnectIsServer);  != nil {
		return true, false, .(string)
	}
	return false, false, ""
}

// WithNoDial constructs a new context with an option that instructs the network
// to not attempt a new dial when opening a stream.
func ( context.Context,  string) context.Context {
	return context.WithValue(, noDial, )
}

// GetNoDial returns true if the no dial option is set in the context.
func ( context.Context) ( bool,  string) {
	 := .Value(noDial)
	if  != nil {
		return true, .(string)
	}

	return false, ""
}

// GetDialPeerTimeout returns the current DialPeer timeout (or the default).
func ( context.Context) time.Duration {
	if ,  := .Value(dialPeerTimeoutCtxKey{}).(time.Duration);  {
		return 
	}
	return DialPeerTimeout
}

// WithDialPeerTimeout returns a new context with the DialPeer timeout applied.
//
// This timeout overrides the default DialPeerTimeout and applies per-dial
// independently.
func ( context.Context,  time.Duration) context.Context {
	return context.WithValue(, dialPeerTimeoutCtxKey{}, )
}

// WithAllowLimitedConn constructs a new context with an option that instructs
// the network that it is acceptable to use a limited connection when opening a
// new stream.
func ( context.Context,  string) context.Context {
	return context.WithValue(, allowLimitedConn, )
}

// WithUseTransient constructs a new context with an option that instructs the network
// that it is acceptable to use a transient connection when opening a new stream.
//
// Deprecated: Use WithAllowLimitedConn instead.
func ( context.Context,  string) context.Context {
	return context.WithValue(, allowLimitedConn, )
}

// GetAllowLimitedConn returns true if the allow limited conn option is set in the context.
func ( context.Context) ( bool,  string) {
	 := .Value(allowLimitedConn)
	if  != nil {
		return true, .(string)
	}
	return false, ""
}

// GetUseTransient returns true if the use transient option is set in the context.
//
// Deprecated: Use GetAllowLimitedConn instead.
func ( context.Context) ( bool,  string) {
	 := .Value(allowLimitedConn)
	if  != nil {
		return true, .(string)
	}
	return false, ""
}