-- | libp2p-hs: Haskell implementation of the libp2p networking stack.
--
-- This is the public API facade for the library. Import this module
-- for the common types and functions needed to build a libp2p node:
--
-- @
-- import LibP2P
--
-- main :: IO ()
-- main = do
--   (pid, kp) <- generateAndPeerId
--   sw <- newSwitch pid kp
--   tcp <- newTCPTransport
--   addTransport sw tcp
--   registerIdentifyHandlers sw
--   registerPingHandler sw
--   _relayState <- registerNATHandlers sw defaultNATConfig
--   addrs <- switchListen sw defaultConnectionGater [fromText "/ip4/127.0.0.1/tcp/0"]
--   print addrs
--   -- ... dial other peers, etc.
--   switchClose sw
-- @
module LibP2P
  ( -- * Identity
    PeerId
  , KeyPair
  , generateKeyPair
  , fromPublicKey
  , peerIdBytes
  , toBase58
  , parsePeerId
  , toCIDv1

    -- * Addressing
  , Multiaddr (..)
  , Protocol (..)
  , splitP2P
  , toText
  , fromText

    -- * Switch (central coordinator)
  , Switch
  , newSwitch
  , addTransport
  , switchListen
  , switchListenAddrs
  , switchClose
  , dial
  , closeConnection
  , newStream
  , DialError (..)
  , ResourceError (..)
  , setStreamHandler
  , removeStreamHandler
  , StreamIO (..)
  , StreamHandler
  , ProtocolId
  , Connection (..)

    -- * Transport
  , Transport (..)
  , newTCPTransport

    -- * Connection gating
  , ConnectionGater (..)
  , defaultConnectionGater

    -- * Identify protocol
  , registerIdentifyHandlers
  , requestIdentify
  , pushIdentify

    -- * Ping protocol
  , registerPingHandler
  , sendPing
  , PingSession
  , openPingSession
  , ping
  , pingWithTimeout
  , closePingSession
  , withPingSession
  , PingResult (..)
  , PingError (..)

    -- * NAT traversal (AutoNAT, Circuit Relay v2, DCUtR)
  , NATConfig (..)
  , defaultNATConfig
  , registerNATHandlers
  , registerAutoNATHandler
  , registerRelayHopHandler
  , registerRelayStopHandler
  , registerDCUtRHandler
  , RelayState
  , RelayConfig (..)
  , defaultRelayConfig
  , newRelayState

    -- * GossipSub
  , GossipSubNode (..)
  , GossipSubParams (..)
  , defaultGossipSubParams
  , newGossipSubNode
  , startGossipSub
  , stopGossipSub
  , gossipJoin
  , gossipLeave
  , gossipPublish
  ) where

import LibP2P.Crypto.Ed25519 (generateKeyPair)
import LibP2P.Crypto.Key (KeyPair)
import LibP2P.Crypto.PeerId (PeerId, fromPublicKey, peerIdBytes, toBase58, parsePeerId, toCIDv1)
import LibP2P.Multiaddr (Multiaddr (..), fromText, splitP2P, toText)
import LibP2P.Multiaddr.Protocol (Protocol (..))
import LibP2P.MultistreamSelect.Negotiation (ProtocolId, StreamIO (..))
import LibP2P.NAT
  ( NATConfig (..)
  , defaultNATConfig
  , registerAutoNATHandler
  , registerDCUtRHandler
  , registerNATHandlers
  , registerRelayHopHandler
  , registerRelayStopHandler
  )
import LibP2P.NAT.Relay (RelayConfig (..), RelayState, defaultRelayConfig, newRelayState)
import LibP2P.Protocol.GossipSub.Handler
  ( GossipSubNode (..)
  , gossipJoin
  , gossipLeave
  , gossipPublish
  , newGossipSubNode
  , startGossipSub
  , stopGossipSub
  )
import LibP2P.Protocol.GossipSub.Types (GossipSubParams (..), defaultGossipSubParams)
import LibP2P.Protocol.Identify (pushIdentify, registerIdentifyHandlers, requestIdentify)
import LibP2P.Protocol.Ping
  ( PingError (..)
  , PingResult (..)
  , PingSession
  , closePingSession
  , openPingSession
  , ping
  , pingWithTimeout
  , registerPingHandler
  , sendPing
  , withPingSession
  )
import LibP2P.Switch.Connection (closeConnection, newStream)
import LibP2P.Switch.Dial (dial)
import LibP2P.Switch.Listen (ConnectionGater (..), defaultConnectionGater, switchListen, switchListenAddrs)
import LibP2P.Switch (addTransport, newSwitch, removeStreamHandler, setStreamHandler, switchClose)
import LibP2P.Switch.Types (Connection (..), DialError (..), ResourceError (..), StreamHandler, Switch)
import LibP2P.Transport.TCP (newTCPTransport)
import LibP2P.Transport (Transport (..))