-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | An IRC client library.
--   
--   An IRC client library built atop <a>irc-conduit</a>. Why another IRC
--   client library, you cry? I didn't really find one that did what I
--   wanted (specifically, handle connecting to servers and calling event
--   handlers, possibly with TLS), but which didn't implement almost a full
--   IRC bot for you. That takes out all the fun!
--   
--   <a>irc-conduit</a> and <a>irc-ctcp</a> are my solution to the first
--   part of that, this is my solution to the latter. It's a simple IRC
--   client library that does the basics for you, but isn't an all-singing,
--   all-dancing, fully-featured IRC <i>application</i>. It is a merely a
--   simple library.
@package irc-client
@version 0.4.4.2


module Network.IRC.Client.Types
type UnicodeEvent = Event Text
type UnicodeSource = Source Text
type UnicodeMessage = Message Text

-- | The IRC monad.
type IRC a = StatefulIRC () a

-- | The IRC monad, with state.
type StatefulIRC s a = ReaderT (IRCState s) IO a
data IRCState s
IRCState :: ConnectionConfig s -> TVar s -> TVar (InstanceConfig s) -> TVar ConnectionState -> IRCState s

-- | Read-only connection configuration
[_connectionConfig] :: IRCState s -> ConnectionConfig s

-- | Mutable user state
[_userState] :: IRCState s -> TVar s

-- | Mutable instance configuration in STM
[_instanceConfig] :: IRCState s -> TVar (InstanceConfig s)

-- | State of the connection.
[_connState] :: IRCState s -> TVar ConnectionState

-- | The state of the connection.
data ConnectionState
Connected :: ConnectionState
Disconnecting :: ConnectionState
Disconnected :: ConnectionState

-- | Construct a new IRC state
newIRCState :: MonadIO m => ConnectionConfig s -> InstanceConfig s -> s -> m (IRCState s)

-- | Access the client state.
ircState :: StatefulIRC s (IRCState s)

-- | Extract the connection configuration from an IRC state
getConnectionConfig :: IRCState s -> ConnectionConfig s

-- | Extract the instance configuration from an IRC state
getInstanceConfig :: IRCState s -> TVar (InstanceConfig s)

-- | Extract the user state from an IRC state
getUserState :: IRCState s -> TVar s

-- | Extract the connection state from an IRC state.
getConnState :: MonadIO m => IRCState s -> m ConnectionState

-- | Extract the current snapshot of the instance configuration from an IRC
--   state
getInstanceConfig' :: MonadIO m => IRCState s -> m (InstanceConfig s)

-- | Access the connection config
connectionConfig :: StatefulIRC s (ConnectionConfig s)

-- | Access the instance config TVar
instanceConfigTVar :: StatefulIRC s (TVar (InstanceConfig s))

-- | Access the instance config as it is right now.
instanceConfig :: StatefulIRC s (InstanceConfig s)

-- | Overwrite the instance config, even if it has changed since we looked
--   at it.
putInstanceConfig :: InstanceConfig s -> StatefulIRC s ()

-- | Access the user state.
stateTVar :: StatefulIRC s (TVar s)

-- | Access the user state as it is right now.
state :: StatefulIRC s s

-- | Set the user state.
putState :: s -> StatefulIRC s ()

-- | The origin of a message.
data Origin
FromServer :: Origin
FromClient :: Origin

-- | The static state of an IRC server connection.
data ConnectionConfig s
ConnectionConfig :: (IO () -> Consumer (Either ByteString IrcEvent) IO () -> Producer IO IrcMessage -> IO ()) -> TBMChan IrcMessage -> ByteString -> Int -> NominalDiffTime -> StatefulIRC s () -> StatefulIRC s () -> (Origin -> ByteString -> IO ()) -> ConnectionConfig s

-- | Function to connect and start the conduits.
[_func] :: ConnectionConfig s -> IO () -> Consumer (Either ByteString IrcEvent) IO () -> Producer IO IrcMessage -> IO ()

-- | Message send queue.
[_sendqueue] :: ConnectionConfig s -> TBMChan IrcMessage

-- | The server host.
[_server] :: ConnectionConfig s -> ByteString

-- | The server port.
[_port] :: ConnectionConfig s -> Int

-- | The minimum time between two adjacent messages.
[_flood] :: ConnectionConfig s -> NominalDiffTime

-- | Action to run after successfully connecting to the server and setting
--   the nick.
[_onconnect] :: ConnectionConfig s -> StatefulIRC s ()

-- | Action to run if the remote server closes the connection.
[_ondisconnect] :: ConnectionConfig s -> StatefulIRC s ()

-- | Function to log messages sent to and received from the server.
[_logfunc] :: ConnectionConfig s -> Origin -> ByteString -> IO ()

-- | The updateable state of an IRC connection.
data InstanceConfig s
InstanceConfig :: Text -> Text -> Text -> Maybe Text -> [Text] -> Text -> [EventHandler s] -> [(Text, Maybe Text)] -> InstanceConfig s

-- | Client nick
[_nick] :: InstanceConfig s -> Text

-- | Client username
[_username] :: InstanceConfig s -> Text

-- | Client realname
[_realname] :: InstanceConfig s -> Text

-- | Client password
[_password] :: InstanceConfig s -> Maybe Text

-- | Current channels
[_channels] :: InstanceConfig s -> [Text]

-- | Response to CTCP VERSION
[_ctcpVer] :: InstanceConfig s -> Text

-- | The registered event handlers
[_eventHandlers] :: InstanceConfig s -> [EventHandler s]

-- | List of nicks (optionally restricted to channels) to ignore messages
--   from. No channel = global.
[_ignore] :: InstanceConfig s -> [(Text, Maybe Text)]

-- | Types of events which can be caught.
data EventType

-- | Match all events
EEverything :: EventType

-- | Match no events
ENothing :: EventType
EPrivmsg :: EventType
ENotice :: EventType
ECTCP :: EventType
ENick :: EventType
EJoin :: EventType
EPart :: EventType
EQuit :: EventType
EMode :: EventType
ETopic :: EventType
EInvite :: EventType
EKick :: EventType
EPing :: EventType
ENumeric :: EventType

-- | A function which handles an event.
data EventHandler s
EventHandler :: Text -> EventType -> (UnicodeEvent -> StatefulIRC s ()) -> EventHandler s

-- | A description of the event handler.
[_description] :: EventHandler s -> Text

-- | Which type to be triggered by
[_matchType] :: EventHandler s -> EventType

-- | The function to call.
[_eventFunc] :: EventHandler s -> UnicodeEvent -> StatefulIRC s ()

-- | Get the type of an event.
eventType :: Event a -> EventType

-- | A decoded IRC message + source.
data Event a :: * -> *
Event :: ByteString -> Source a -> Message a -> Event a

-- | The message as a bytestring.
[_raw] :: Event a -> ByteString

-- | The source of the message (user, channel, or server).
[_source] :: Event a -> Source a

-- | The decoded message. This will never be a <a>RawMsg</a>.
[_message] :: Event a -> Message a

-- | The source of an IRC message.
data Source a :: * -> *

-- | The message comes directly from a user.
User :: NickName a -> Source a

-- | The message comes from a user in a channel.
Channel :: ChannelName a -> NickName a -> Source a

-- | The message comes directly from the server.
Server :: ServerName a -> Source a

-- | A decoded IRC message.
data Message a :: * -> *

-- | A message, either from a user or to a channel the client is in. CTCPs
--   are distinguished by starting and ending with a \001 (SOH).
Privmsg :: Target a -> Either CTCPByteString a -> Message a

-- | Like a privmsg, but should not provoke an automatic response.
Notice :: Target a -> Either CTCPByteString a -> Message a

-- | Someone has updated their nick.
Nick :: NickName a -> Message a

-- | Someone has joined a channel.
Join :: ChannelName a -> Message a

-- | Someone has left a channel.
Part :: ChannelName a -> Reason a -> Message a

-- | Someone has left the network.
Quit :: Reason a -> Message a

-- | Someone has set some channel modes or user modes.
Mode :: Target a -> IsModeSet -> [ModeFlag a] -> [ModeArg a] -> Message a

-- | Someone has set the topic of a channel.
Topic :: ChannelName a -> a -> Message a

-- | The client has been invited to a channel.
Invite :: ChannelName a -> NickName a -> Message a

-- | Someone has been kicked from a channel.
Kick :: ChannelName a -> NickName a -> Reason a -> Message a

-- | The client has received a server ping, and should send a pong asap.
Ping :: ServerName a -> Maybe (ServerName a) -> Message a

-- | A pong sent to the named server.
Pong :: ServerName a -> Message a

-- | One of the many server numeric responses.
Numeric :: Int -> [NumericArg a] -> Message a

-- | Never produced by decoding, but can be used to send arbitrary
--   bytestrings to the IRC server. Naturally, this should only be used
--   when you are confident that the produced bytestring will be a valid
--   IRC message.
RawMsg :: a -> Message a
instance GHC.Show.Show Network.IRC.Client.Types.EventType
instance GHC.Classes.Eq Network.IRC.Client.Types.EventType
instance GHC.Show.Show Network.IRC.Client.Types.Origin
instance GHC.Read.Read Network.IRC.Client.Types.Origin
instance GHC.Classes.Eq Network.IRC.Client.Types.Origin
instance GHC.Show.Show Network.IRC.Client.Types.ConnectionState
instance GHC.Read.Read Network.IRC.Client.Types.ConnectionState
instance GHC.Classes.Ord Network.IRC.Client.Types.ConnectionState
instance GHC.Classes.Eq Network.IRC.Client.Types.ConnectionState
instance GHC.Enum.Enum Network.IRC.Client.Types.ConnectionState
instance GHC.Enum.Bounded Network.IRC.Client.Types.ConnectionState


-- | Most of the hairy code. This isn't all internal, due to messy
--   dependencies, but I've tried to make this as "internal" as reasonably
--   possible.
--   
--   This module is NOT considered to form part of the public interface of
--   this library.
module Network.IRC.Client.Internal

-- | Connect to a server using the supplied connection function.
connectInternal :: MonadIO m => (IO () -> Consumer (Either ByteString IrcEvent) IO () -> Producer IO IrcMessage -> IO ()) -> StatefulIRC s () -> StatefulIRC s () -> (Origin -> ByteString -> IO ()) -> ByteString -> Int -> NominalDiffTime -> m (ConnectionConfig s)

-- | The event loop.
runner :: StatefulIRC s ()

-- | Forget failed decodings.
forgetful :: Monad m => Conduit (Either a b) m b

-- | Block on receiving a message and invoke all matching handlers
--   concurrently.
eventSink :: MonadIO m => IRCState s -> Consumer IrcEvent m ()

-- | Check if an event is ignored or not.
isIgnored :: MonadIO m => IRCState s -> UnicodeEvent -> m Bool

-- | Get the event handlers for an event.
getHandlersFor :: Event a -> [EventHandler s] -> [UnicodeEvent -> StatefulIRC s ()]

-- | A conduit which logs everything which goes through it.
logConduit :: MonadIO m => (a -> IO ()) -> Conduit a m a

-- | Print messages to stdout, with the current time.
stdoutLogger :: Origin -> ByteString -> IO ()

-- | Append messages to a file, with the current time.
fileLogger :: FilePath -> Origin -> ByteString -> IO ()

-- | Do no logging.
noopLogger :: a -> b -> IO ()

-- | Send a message as UTF-8, using TLS if enabled. This blocks if messages
--   are sent too rapidly.
send :: UnicodeMessage -> StatefulIRC s ()

-- | Send a message, using TLS if enabled. This blocks if messages are sent
--   too rapidly.
sendBS :: IrcMessage -> StatefulIRC s ()

-- | Disconnect from the server, properly tearing down the TLS session (if
--   there is one).
disconnect :: StatefulIRC s ()

-- | Disconnect immediately, without waiting for messages to be sent.
disconnectNow :: StatefulIRC s ()

-- | Block until an action is successful or a timeout is reached.
timeout :: MonadIO m => NominalDiffTime -> IO Bool -> m ()


-- | Commonly-used utility functions for IRC clients.
module Network.IRC.Client.Utils

-- | Update the nick in the instance configuration and also send an update
--   message to the server. This doesn't attempt to resolve nick
--   collisions, that's up to the event handlers.
setNick :: Text -> StatefulIRC s ()

-- | Update the channel list in the instance configuration and also part
--   the channel.
leaveChannel :: Text -> Maybe Text -> StatefulIRC s ()

-- | Remove a channel from the list without sending a part command (be
--   careful not to let the channel list get out of sync with the
--   real-world state if you use it for anything!)
delChan :: TVar (InstanceConfig s) -> Text -> STM ()

-- | Add an event handler
addHandler :: EventHandler s -> StatefulIRC s ()

-- | Send a message to the source of an event.
reply :: UnicodeEvent -> Text -> StatefulIRC s ()

-- | Construct a <tt>PRIVMSG</tt> containing a CTCP
ctcp :: Text -> Text -> [Text] -> UnicodeMessage

-- | Construct a <tt>NOTICE</tt> containing a CTCP
ctcpReply :: Text -> Text -> [Text] -> UnicodeMessage

-- | Check if the client is connected.
isConnected :: StatefulIRC s Bool

-- | Check if the client is in the process of disconnecting.
isDisconnecting :: StatefulIRC s Bool

-- | Check if the client is disconnected
isDisconnected :: StatefulIRC s Bool


-- | The default event handlers. Handlers are invoked concurrently when
--   matching events are received from the server.
module Network.IRC.Client.Handlers

-- | The default event handlers, the following are included:
--   
--   <ul>
--   <li>respond to server <tt>PING</tt> messages with a
--   <tt>PONG</tt>;</li>
--   <li>respond to CTCP <tt>PING</tt> requests with a CTCP
--   <tt>PONG</tt>;</li>
--   <li>respond to CTCP <tt>VERSION</tt> requests with the version
--   string;</li>
--   <li>respond to CTCP <tt>TIME</tt> requests with the system time;</li>
--   <li>update the nick upon receiving the welcome message, in case the
--   server modifies it;</li>
--   <li>mangle the nick if the server reports a collision;</li>
--   <li>update the channel list on <tt>JOIN</tt> and <tt>KICK</tt>.</li>
--   </ul>
--   
--   These event handlers are all exposed through the
--   Network.IRC.Client.Handlers module, so you can use them directly if
--   you are building up your <a>InstanceConfig</a> from scratch.
--   
--   If you are building a bot, you may want to write an event handler to
--   process messages representing commands.
defaultEventHandlers :: [EventHandler s]

-- | Respond to server <tt>PING</tt> messages with a <tt>PONG</tt>.
pingHandler :: UnicodeEvent -> StatefulIRC s ()

-- | Respond to CTCP <tt>PING</tt> requests with a CTCP <tt>PONG</tt>.
ctcpPingHandler :: UnicodeEvent -> StatefulIRC s ()

-- | Respond to CTCP <tt>VERSION</tt> requests with the version string.
ctcpVersionHandler :: UnicodeEvent -> StatefulIRC s ()

-- | Respond to CTCP <tt>TIME</tt> requests with the system time.
ctcpTimeHandler :: UnicodeEvent -> StatefulIRC s ()

-- | Update the nick upon welcome (numeric reply 001), as it may not be
--   what we requested (eg, in the case of a nick too long).
welcomeNick :: UnicodeEvent -> StatefulIRC s ()

-- | Join default channels upon welcome (numeric reply 001). If sent
--   earlier, the server might reject the JOIN attempts.
joinOnWelcome :: UnicodeEvent -> StatefulIRC s ()

-- | Mangle the nick if there's a collision (numeric replies 432, 433, and
--   436) when we set it
nickMangler :: UnicodeEvent -> StatefulIRC s ()

-- | The default connect handler: set the nick.
defaultOnConnect :: StatefulIRC s ()

-- | The default disconnect handler: do nothing. You might want to override
--   this with one which reconnects.
defaultOnDisconnect :: StatefulIRC s ()


-- | A simple IRC client library. Typical usage will be of this form:
--   
--   <pre>
--   run :: ByteString -&gt; Int -&gt; Text -&gt; IO ()
--   run host port nick = do
--     conn &lt;- connect host port 1
--     let cfg = defaultIRCConf nick
--     let cfg' = cfg { _eventHandlers = yourCustomEventHandlers : _eventHandlers cfg }
--     start conn cfg'
--   </pre>
--   
--   You shouldn't really need to tweak anything other than the event
--   handlers, as everything has been designed to be as simple as possible.
module Network.IRC.Client

-- | Connect to a server without TLS.
connect :: MonadIO m => ByteString -> Int -> NominalDiffTime -> m (ConnectionConfig s)

-- | Connect to a server with TLS.
connectWithTLS :: MonadIO m => ByteString -> Int -> NominalDiffTime -> m (ConnectionConfig s)

-- | Connect to a server with TLS using the given TLS config.
connectWithTLSConfig :: MonadIO m => TLSClientConfig -> NominalDiffTime -> m (ConnectionConfig s)

-- | Connect to a server with TLS using the given certificate verifier.
connectWithTLSVerify :: MonadIO m => (CertificateStore -> ValidationCache -> ServiceID -> CertificateChain -> IO [FailedReason]) -> ByteString -> Int -> NominalDiffTime -> m (ConnectionConfig s)

-- | Run the event loop for a server, receiving messages and handing them
--   off to handlers as appropriate. Messages will be logged to stdout.
start :: MonadIO m => ConnectionConfig () -> InstanceConfig () -> m ()

-- | Like <a>start</a>, but use the provided initial state.
start' :: MonadIO m => IRCState s -> m ()

-- | like <a>start</a> but for clients with state.
startStateful :: MonadIO m => ConnectionConfig s -> InstanceConfig s -> s -> m ()

-- | The origin of a message.
data Origin
FromServer :: Origin
FromClient :: Origin

-- | Connect to a server without TLS, with the provided logging function.
connect' :: MonadIO m => (Origin -> ByteString -> IO ()) -> ByteString -> Int -> NominalDiffTime -> m (ConnectionConfig s)

-- | Connect to a server with TLS, with the provided logging function.
connectWithTLS' :: MonadIO m => (Origin -> ByteString -> IO ()) -> ByteString -> Int -> NominalDiffTime -> m (ConnectionConfig s)

-- | Connect to a server with TLS using the given TLS config, with the
--   provided logging function.
connectWithTLSConfig' :: MonadIO m => (Origin -> ByteString -> IO ()) -> TLSClientConfig -> NominalDiffTime -> m (ConnectionConfig s)

-- | Connect to a server with TLS using the given certificate verifier,
--   with the provided logging function.
connectWithTLSVerify' :: MonadIO m => (Origin -> ByteString -> IO ()) -> (CertificateStore -> ValidationCache -> ServiceID -> CertificateChain -> IO [FailedReason]) -> ByteString -> Int -> NominalDiffTime -> m (ConnectionConfig s)

-- | Print messages to stdout, with the current time.
stdoutLogger :: Origin -> ByteString -> IO ()

-- | Append messages to a file, with the current time.
fileLogger :: FilePath -> Origin -> ByteString -> IO ()

-- | Do no logging.
noopLogger :: a -> b -> IO ()

-- | Send a message as UTF-8, using TLS if enabled. This blocks if messages
--   are sent too rapidly.
send :: UnicodeMessage -> StatefulIRC s ()

-- | Send a message, using TLS if enabled. This blocks if messages are sent
--   too rapidly.
sendBS :: IrcMessage -> StatefulIRC s ()

-- | Disconnect from the server, properly tearing down the TLS session (if
--   there is one).
disconnect :: StatefulIRC s ()

-- | Construct a default IRC configuration from a nick
defaultIRCConf :: Text -> InstanceConfig s

-- | The default connect handler: set the nick.
defaultOnConnect :: StatefulIRC s ()

-- | The default disconnect handler: do nothing. You might want to override
--   this with one which reconnects.
defaultOnDisconnect :: StatefulIRC s ()

-- | The default event handlers, the following are included:
--   
--   <ul>
--   <li>respond to server <tt>PING</tt> messages with a
--   <tt>PONG</tt>;</li>
--   <li>respond to CTCP <tt>PING</tt> requests with a CTCP
--   <tt>PONG</tt>;</li>
--   <li>respond to CTCP <tt>VERSION</tt> requests with the version
--   string;</li>
--   <li>respond to CTCP <tt>TIME</tt> requests with the system time;</li>
--   <li>update the nick upon receiving the welcome message, in case the
--   server modifies it;</li>
--   <li>mangle the nick if the server reports a collision;</li>
--   <li>update the channel list on <tt>JOIN</tt> and <tt>KICK</tt>.</li>
--   </ul>
--   
--   These event handlers are all exposed through the
--   Network.IRC.Client.Handlers module, so you can use them directly if
--   you are building up your <a>InstanceConfig</a> from scratch.
--   
--   If you are building a bot, you may want to write an event handler to
--   process messages representing commands.
defaultEventHandlers :: [EventHandler s]

-- | Construct a raw message.
rawMessage :: ByteString -> [ByteString] -> IrcMessage

-- | Encode an IRC message into a single bytestring suitable for sending to
--   the server.
toByteString :: IrcMessage -> ByteString
