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


-- | Lambdabot core functionality
--   
--   Lambdabot is an IRC bot written over several years by those on the
--   #haskell IRC channel.
--   
--   Manage plugins, network connections, configurations and much more.
@package lambdabot-core
@version 5.3.1.2


-- | Time compatibility layer (stuff to support old lambdabot state
--   serialization formats)
--   
--   TODO: trim this down to just the explicitly serialization-related
--   stuff
module Lambdabot.Compat.AltTime

-- | Wrapping ClockTime (which doesn't provide a Read instance!) seems
--   easier than talking care of the serialization of UserStatus ourselves.
data ClockTime

-- | Retrieve the current clocktime
getClockTime :: IO ClockTime

-- | Difference of two clock times
diffClockTimes :: ClockTime -> ClockTime -> TimeDiff

-- | <tt><a>addToClockTime</a> d t</tt> adds a time difference <tt>d</tt>
--   and a -- clock time <tt>t</tt> to yield a new clock time.
addToClockTime :: TimeDiff -> ClockTime -> ClockTime

-- | Pretty-print a TimeDiff. Both positive and negative Timediffs produce
--   the same output.
--   
--   14d 17h 8m 53s
timeDiffPretty :: TimeDiff -> String
newtype TimeDiff
TimeDiff :: NominalDiffTime -> TimeDiff
noTimeDiff :: TimeDiff
instance Data.Binary.Class.Binary Lambdabot.Compat.AltTime.ClockTime
instance Data.Binary.Class.Binary Lambdabot.Compat.AltTime.TimeDiff
instance GHC.Classes.Eq Lambdabot.Compat.AltTime.ClockTime
instance GHC.Classes.Eq Lambdabot.Compat.AltTime.TimeDiff
instance GHC.Classes.Ord Lambdabot.Compat.AltTime.TimeDiff
instance GHC.Internal.Read.Read Lambdabot.Compat.AltTime.ClockTime
instance GHC.Internal.Read.Read Lambdabot.Compat.AltTime.TimeDiff
instance GHC.Internal.Show.Show Lambdabot.Compat.AltTime.ClockTime
instance GHC.Internal.Show.Show Lambdabot.Compat.AltTime.TimeDiff


-- | Extensible configuration system for lambdabot
--   
--   TODO: there's notthing lambdabot-specific about this, it could be a
--   useful standalone library.
module Lambdabot.Config
data Config t
getConfigDefault :: Config t -> t
mergeConfig :: Config t -> t -> t -> t
class Monad m => MonadConfig (m :: Type -> Type)
getConfig :: MonadConfig m => Config a -> m a

-- | Define a new configuration key with the specified name, type and
--   default value
--   
--   You should probably also provide an explicit export list for any
--   module that defines config keys, because the definition introduces a
--   few extra types that will clutter up the export list otherwise.
config :: String -> TypeQ -> ExpQ -> Q [Dec]

-- | Like <a>config</a>, but also allowing you to specify a "merge rule"
--   that will be used to combine multiple bindings of the same key.
--   
--   For example, in <a>Lambdabot.Config.Core</a>, <tt>onStartupCmds</tt>
--   is defined as a list of commands to execute on startup. Its default
--   value is ["offlinerc"], so if a user invokes the default lambdabot
--   executable without arguments, they will get a REPL. Each instance of
--   "-e" on the command-line adds a binding of the form:
--   
--   <pre>
--   onStartupCmds :=&gt; [command]
--   </pre>
--   
--   So if they give one "-e", it replaces the default (note that it is
--   _not_ merged with the default - the default is discarded), and if they
--   give more than one they are merged using the specified operation (in
--   this case, <a>(++)</a>).
configWithMerge :: ExpQ -> String -> TypeQ -> ExpQ -> Q [Dec]
instance Data.GADT.Internal.GCompare Lambdabot.Config.Config
instance Data.GADT.Internal.GEq Lambdabot.Config.Config
instance Lambdabot.Config.MonadConfig m => Lambdabot.Config.MonadConfig (Control.Monad.Trans.Reader.ReaderT r m)
instance Lambdabot.Config.MonadConfig m => Lambdabot.Config.MonadConfig (Control.Monad.Trans.State.Lazy.StateT s m)
instance (Lambdabot.Config.MonadConfig m, GHC.Internal.Base.Monoid w) => Lambdabot.Config.MonadConfig (Control.Monad.Trans.Writer.Lazy.WriterT w m)

module Lambdabot.Logging

-- | Priorities are used to define how important a log message is. Users
--   can filter log messages based on priorities.
--   
--   These have their roots on the traditional syslog system. The standard
--   definitions are given below, but you are free to interpret them
--   however you like. They are listed here in ascending importance order.
data Priority

-- | Debug messages
DEBUG :: Priority

-- | Information
INFO :: Priority

-- | Normal runtime conditions
NOTICE :: Priority

-- | General Warnings
WARNING :: Priority

-- | General Errors
ERROR :: Priority

-- | Severe situations
CRITICAL :: Priority

-- | Take immediate action
ALERT :: Priority

-- | System is unusable
EMERGENCY :: Priority
class Monad m => MonadLogging (m :: Type -> Type)
getCurrentLogger :: MonadLogging m => m [String]
logM :: MonadLogging m => String -> Priority -> String -> m ()
debugM :: MonadLogging m => String -> m ()
infoM :: MonadLogging m => String -> m ()
noticeM :: MonadLogging m => String -> m ()
warningM :: MonadLogging m => String -> m ()
errorM :: MonadLogging m => String -> m ()
criticalM :: MonadLogging m => String -> m ()
alertM :: MonadLogging m => String -> m ()
emergencyM :: MonadLogging m => String -> m ()
instance Lambdabot.Logging.MonadLogging GHC.Types.IO


-- | String and other utilities
module Lambdabot.Util

-- | <a>strip</a> takes as input a predicate and a list and strips elements
--   matching the predicate from the prefix as well as the suffix of the
--   list. Example:
--   
--   <pre>
--   strip isSpace "   abc  " ===&gt; "abc"
--   </pre>
strip :: (a -> Bool) -> [a] -> [a]

-- | Drop elements matching a predicate from the end of a list
dropFromEnd :: (a -> Bool) -> [a] -> [a]

-- | Break a String into it's first word, and the rest of the string.
--   Example:
--   
--   <pre>
--   split_first_word "A fine day" ===&gt; ("A", "fine day)
--   </pre>
splitFirstWord :: String -> (String, String)

-- | Truncate a string to the specified length, putting ellipses at the end
--   if necessary.
limitStr :: Int -> String -> String

-- | Form a list of terms using a single conjunction. Example:
--   
--   <pre>
--   listToStr "and" ["a", "b", "c"] ===&gt; "a, b and c"
--   </pre>
listToStr :: String -> [String] -> String

-- | show a list without heavyweight formatting NB: assumes show instance
--   outputs a quoted <a>String</a>. under that assumption, strips the
--   outer quotes.
showClean :: Show a => [a] -> String

-- | untab an string
expandTab :: Int -> String -> String
arePrefixesWithSpaceOf :: [String] -> String -> Bool
arePrefixesOf :: [String] -> String -> Bool
io :: MonadIO m => IO a -> m a
forkUnmasked :: MonadBaseControl IO m => m () -> m ThreadId

-- | Pick a random element of the list.
random :: MonadIO m => [a] -> m a
randomFailureMsg :: (MonadIO m, MonadConfig m) => m String
randomSuccessMsg :: MonadIO m => m String

module Lambdabot.Nick

-- | The type of nicknames isolated from a message.
data Nick
Nick :: !String -> !String -> Nick

-- | The tag of the server this nick is on
[nTag] :: Nick -> !String

-- | The server-specific nickname of this nick
[nName] :: Nick -> !String

-- | Format a nickname for display. This will automatically omit the server
--   field if it is the same as the server of the provided message.
fmtNick :: String -> Nick -> String

-- | Parse a nickname received in a message. If the server field is not
--   provided, it defaults to the same as that of the message.
parseNick :: String -> String -> Nick
instance GHC.Classes.Eq Lambdabot.Nick.Nick
instance GHC.Classes.Ord Lambdabot.Nick.Nick

module Lambdabot.Message
class Show a => Message a

-- | extracts the tag of the server involved in a given message
server :: Message a => a -> String

-- | extracts the nickname involved in a given message.
nick :: Message a => a -> Nick

-- | <a>fullName</a> extracts the full user name involved in a given
--   message.
fullName :: Message a => a -> String

-- | <a>channels</a> extracts the channels a Message operate on.
channels :: Message a => a -> [Nick]
lambdabotName :: Message a => a -> Nick


-- | The IRC module processes the IRC protocol and provides a nice API for
--   sending and receiving IRC messages with an IRC server.
module Lambdabot.IRC

-- | An IRC message is a server, a prefix, a command and a list of
--   parameters.
--   
--   Note that the strings here are treated as lists of bytes!
data IrcMessage
IrcMessage :: !String -> !String -> !String -> !String -> ![String] -> IrcMessage
[ircMsgServer] :: IrcMessage -> !String
[ircMsgLBName] :: IrcMessage -> !String
[ircMsgPrefix] :: IrcMessage -> !String
[ircMsgCommand] :: IrcMessage -> !String
[ircMsgParams] :: IrcMessage -> ![String]
joinChannel :: Nick -> IrcMessage
partChannel :: Nick -> IrcMessage
getTopic :: Nick -> IrcMessage
setTopic :: Nick -> String -> IrcMessage

-- | <a>codepage</a> creates a server CODEPAGE message. The input string
--   given is the codepage name for current session.
codepage :: String -> String -> IrcMessage

-- | <a>privmsg</a> creates a private message to the person designated.
privmsg :: Nick -> String -> IrcMessage

-- | <a>quit</a> creates a server QUIT message. The input string given is
--   the quit message, given to other parties when leaving the network.
quit :: String -> String -> IrcMessage

-- | Construct a privmsg from the CTCP TIME notice, to feed up to the
--   @localtime-reply plugin, which then passes the output to the
--   appropriate client.
timeReply :: IrcMessage -> IrcMessage
pass :: String -> String -> IrcMessage
user :: String -> String -> String -> String -> IrcMessage
setNick :: Nick -> IrcMessage
instance Lambdabot.Message.Message Lambdabot.IRC.IrcMessage
instance GHC.Internal.Show.Show Lambdabot.IRC.IrcMessage

module Lambdabot.Compat.PackedNick

-- | The type of nicknames
type PackedNick = ByteString

-- | Pack a nickname into a ByteString. Note that the resulting strings are
--   not optimally formatted for human consumtion.
packNick :: Nick -> ByteString

-- | Unpack a nickname packed by <a>packNick</a>.
unpackNick :: ByteString -> Nick

module Lambdabot.Command
data Command (m :: Type -> Type)
Command :: String -> [String] -> Bool -> Cmd m () -> (String -> Cmd m ()) -> Command (m :: Type -> Type)
[cmdName] :: Command (m :: Type -> Type) -> String
[aliases] :: Command (m :: Type -> Type) -> [String]
[privileged] :: Command (m :: Type -> Type) -> Bool
[help] :: Command (m :: Type -> Type) -> Cmd m ()
[process] :: Command (m :: Type -> Type) -> String -> Cmd m ()
cmdNames :: forall (m :: Type -> Type). Command m -> [String]
command :: String -> Command Identity
runCommand :: (Monad m, Message a) => Command m -> a -> Nick -> String -> String -> m [String]
data Cmd (m :: Type -> Type) a
execCmd :: (Monad m, Message a) => Cmd m t -> a -> Nick -> String -> m [String]
getCmdName :: forall (m :: Type -> Type). Monad m => Cmd m String
withMsg :: forall (m :: Type -> Type) t. Monad m => (forall a. Message a => a -> Cmd m t) -> Cmd m t
readNick :: forall (m :: Type -> Type). Monad m => String -> Cmd m Nick
showNick :: forall (m :: Type -> Type). Monad m => Nick -> Cmd m String
getServer :: forall (m :: Type -> Type). Monad m => Cmd m String
getSender :: forall (m :: Type -> Type). Monad m => Cmd m Nick
getTarget :: forall (m :: Type -> Type). Monad m => Cmd m Nick
getLambdabotName :: forall (m :: Type -> Type). Monad m => Cmd m Nick
say :: forall (m :: Type -> Type). Monad m => String -> Cmd m ()
instance GHC.Internal.Base.Applicative f => GHC.Internal.Base.Applicative (Lambdabot.Command.Cmd f)
instance GHC.Internal.Base.Functor f => GHC.Internal.Base.Functor (Lambdabot.Command.Cmd f)
instance Control.Monad.Trans.Control.MonadBaseControl b m => Control.Monad.Trans.Control.MonadBaseControl b (Lambdabot.Command.Cmd m)
instance Control.Monad.Base.MonadBase b m => Control.Monad.Base.MonadBase b (Lambdabot.Command.Cmd m)
instance GHC.Internal.Base.Monad m => GHC.Internal.Base.Monad (Lambdabot.Command.Cmd m)
instance Lambdabot.Config.MonadConfig m => Lambdabot.Config.MonadConfig (Lambdabot.Command.Cmd m)
instance GHC.Internal.Control.Monad.Fail.MonadFail m => GHC.Internal.Control.Monad.Fail.MonadFail (Lambdabot.Command.Cmd m)
instance Control.Monad.IO.Class.MonadIO m => Control.Monad.IO.Class.MonadIO (Lambdabot.Command.Cmd m)
instance Lambdabot.Logging.MonadLogging m => Lambdabot.Logging.MonadLogging (Lambdabot.Command.Cmd m)
instance Control.Monad.Trans.Class.MonadTrans Lambdabot.Command.Cmd
instance Control.Monad.Trans.Control.MonadTransControl Lambdabot.Command.Cmd

module Lambdabot.ChanName
data ChanName
mkCN :: Nick -> ChanName
getCN :: ChanName -> Nick
instance GHC.Classes.Eq Lambdabot.ChanName.ChanName
instance GHC.Classes.Ord Lambdabot.ChanName.ChanName

module Lambdabot.Util.Network

-- | This is essentially a reimplementation of the former Network.connectTo
--   function, except that we don't do the service name lookup.
connectTo' :: HostName -> PortNumber -> IO Handle

module Lambdabot.Module

-- | The Module type class.
data Module st
Module :: !Maybe (Serial st) -> !LB st -> !Bool -> !ModuleT st LB [Command (ModuleT st LB)] -> !ModuleT st LB () -> !ModuleT st LB () -> !String -> Cmd (ModuleT st LB) () -> Module st

-- | If the module wants its state to be saved, this function should return
--   a Serial.
--   
--   The default implementation returns Nothing.
[moduleSerialize] :: Module st -> !Maybe (Serial st)

-- | If the module maintains state, this method specifies the default state
--   (for example in case the state can't be read from a state).
--   
--   The default implementation returns an error and assumes the state is
--   never accessed.
[moduleDefState] :: Module st -> !LB st

-- | Is the module sticky? Sticky modules (as well as static ones) can't be
--   unloaded. By default, modules are not sticky.
[moduleSticky] :: Module st -> !Bool

-- | The commands the module listens to.
[moduleCmds] :: Module st -> !ModuleT st LB [Command (ModuleT st LB)]

-- | Initialize the module. The default implementation does nothing.
[moduleInit] :: Module st -> !ModuleT st LB ()

-- | Finalize the module. The default implementation does nothing.
[moduleExit] :: Module st -> !ModuleT st LB ()

-- | Process contextual input. A plugin that implements <a>contextual</a>
--   is able to respond to text not part of a normal command.
[contextual] :: Module st -> !String -> Cmd (ModuleT st LB) ()
newModule :: Module st
data ModuleID st
newModuleID :: IO (ModuleID st)

-- | Info about a running module.
data ModuleInfo st
ModuleInfo :: !String -> !ModuleID st -> !Module st -> !MVar st -> ModuleInfo st
[moduleName] :: ModuleInfo st -> !String
[moduleID] :: ModuleInfo st -> !ModuleID st
[theModule] :: ModuleInfo st -> !Module st
[moduleState] :: ModuleInfo st -> !MVar st

-- | This transformer encodes the additional information a module might
--   need to access its name or its state.
data ModuleT st (m :: Type -> Type) a
runModuleT :: ModuleT st m a -> ModuleInfo st -> m a
instance GHC.Internal.Base.Applicative m => GHC.Internal.Base.Applicative (Lambdabot.Module.ModuleT st m)
instance GHC.Internal.Base.Functor m => GHC.Internal.Base.Functor (Lambdabot.Module.ModuleT st m)
instance Data.GADT.Internal.GCompare Lambdabot.Module.ModuleID
instance Data.GADT.Internal.GEq Lambdabot.Module.ModuleID
instance Control.Monad.Trans.Control.MonadBaseControl b m => Control.Monad.Trans.Control.MonadBaseControl b (Lambdabot.Module.ModuleT st m)
instance Control.Monad.Base.MonadBase b m => Control.Monad.Base.MonadBase b (Lambdabot.Module.ModuleT st m)
instance Control.Monad.Catch.MonadCatch m => Control.Monad.Catch.MonadCatch (Lambdabot.Module.ModuleT st m)
instance Lambdabot.Config.MonadConfig m => Lambdabot.Config.MonadConfig (Lambdabot.Module.ModuleT st m)
instance GHC.Internal.Control.Monad.Fail.MonadFail m => GHC.Internal.Control.Monad.Fail.MonadFail (Lambdabot.Module.ModuleT st m)
instance Control.Monad.IO.Class.MonadIO m => Control.Monad.IO.Class.MonadIO (Lambdabot.Module.ModuleT st m)
instance Lambdabot.Logging.MonadLogging m => Lambdabot.Logging.MonadLogging (Lambdabot.Module.ModuleT st m)
instance Control.Monad.Catch.MonadMask m => Control.Monad.Catch.MonadMask (Lambdabot.Module.ModuleT st m)
instance GHC.Internal.Base.Monad m => GHC.Internal.Base.Monad (Lambdabot.Module.ModuleT st m)
instance GHC.Internal.Base.Monad m => Control.Monad.Reader.Class.MonadReader (Lambdabot.Module.ModuleInfo st) (Lambdabot.Module.ModuleT st m)
instance Control.Monad.Catch.MonadThrow m => Control.Monad.Catch.MonadThrow (Lambdabot.Module.ModuleT st m)
instance Control.Monad.Trans.Control.MonadTransControl (Lambdabot.Module.ModuleT st)
instance Control.Monad.Trans.Class.MonadTrans (Lambdabot.Module.ModuleT st)

module Lambdabot.Monad

-- | Global read-only state.
data IRCRState

-- | Default ro state
initRoState :: [DSum Config Identity] -> IO IRCRState
reportInitDone :: LB ()
waitForInit :: MonadLB m => m ()
waitForQuit :: MonadLB m => m ()
type Callback st = IrcMessage -> ModuleT st LB ()
type OutputFilter st = Nick -> [String] -> ModuleT st LB [String]
type Server st = IrcMessage -> ModuleT st LB ()

-- | Global read/write state.
data IRCRWState
IRCRWState :: Map String (DSum ModuleID ServerRef) -> Set Nick -> Set Nick -> Map ChanName String -> Map String Bool -> Map String (Some ModuleInfo) -> DMap ModuleID ModuleInfo -> Map String (DMap ModuleID CallbackRef) -> [DSum ModuleID OutputFilterRef] -> Map String (DSum ModuleID CommandRef) -> IRCRWState
[ircServerMap] :: IRCRWState -> Map String (DSum ModuleID ServerRef)
[ircPrivilegedUsers] :: IRCRWState -> Set Nick
[ircIgnoredUsers] :: IRCRWState -> Set Nick

-- | maps channel names to topics
[ircChannels] :: IRCRWState -> Map ChanName String

-- | lists servers to which to reconnect on failure (one-time or always)
[ircPersists] :: IRCRWState -> Map String Bool
[ircModulesByName] :: IRCRWState -> Map String (Some ModuleInfo)
[ircModulesByID] :: IRCRWState -> DMap ModuleID ModuleInfo
[ircCallbacks] :: IRCRWState -> Map String (DMap ModuleID CallbackRef)

-- | Output filters, invoked from right to left
[ircOutputFilters] :: IRCRWState -> [DSum ModuleID OutputFilterRef]
[ircCommands] :: IRCRWState -> Map String (DSum ModuleID CommandRef)

-- | Default rw state
initRwState :: IRCRWState

-- | The IRC Monad. The reader transformer holds information about the
--   connection to the IRC server.
--   
--   instances Monad, Functor, MonadIO, MonadState, MonadError
data LB a
runLB :: LB a -> (IRCRState, IORef IRCRWState) -> IO a
class (MonadIO m, MonadBaseControl IO m, MonadConfig m, MonadLogging m, Applicative m, MonadFail m) => MonadLB (m :: Type -> Type)
lb :: MonadLB m => LB a -> m a
registerModule :: String -> Module st -> st -> LB (ModuleInfo st)
registerCommands :: [Command (ModuleT st LB)] -> ModuleT st LB ()
registerCallback :: String -> Callback st -> ModuleT st LB ()
registerOutputFilter :: OutputFilter st -> ModuleT st LB ()
unregisterModule :: String -> LB ()
registerServer :: String -> Server st -> ModuleT st LB ()
unregisterServer :: String -> ModuleT mod LB ()
send :: IrcMessage -> LB ()
received :: IrcMessage -> LB ()
applyOutputFilters :: Nick -> String -> LB [String]

-- | Interpret an expression in the context of a module.
inModuleNamed :: String -> LB a -> (forall st. () => ModuleT st LB a) -> LB a
inModuleWithID :: ModuleID st -> LB a -> ModuleT st LB a -> LB a
withCommand :: String -> LB a -> (forall st. () => Command (ModuleT st LB) -> ModuleT st LB a) -> LB a
listModules :: LB [String]

-- | Interpret a function in the context of all modules
withAllModules :: (forall st. () => ModuleT st LB a) -> LB ()
instance GHC.Internal.Base.Applicative Lambdabot.Monad.LB
instance GHC.Internal.Base.Functor Lambdabot.Monad.LB
instance Control.Monad.Trans.Control.MonadBaseControl GHC.Types.IO Lambdabot.Monad.LB
instance Control.Monad.Base.MonadBase GHC.Types.IO Lambdabot.Monad.LB
instance Control.Monad.Catch.MonadCatch Lambdabot.Monad.LB
instance Lambdabot.Config.MonadConfig Lambdabot.Monad.LB
instance GHC.Internal.Control.Monad.Fail.MonadFail Lambdabot.Monad.LB
instance Control.Monad.IO.Class.MonadIO Lambdabot.Monad.LB
instance GHC.Internal.Base.Monad Lambdabot.Monad.LB
instance Lambdabot.Monad.MonadLB m => Lambdabot.Monad.MonadLB (Lambdabot.Command.Cmd m)
instance Lambdabot.Monad.MonadLB Lambdabot.Monad.LB
instance Lambdabot.Monad.MonadLB m => Lambdabot.Monad.MonadLB (Lambdabot.Module.ModuleT st m)
instance Lambdabot.Logging.MonadLogging Lambdabot.Monad.LB
instance Control.Monad.Catch.MonadMask Lambdabot.Monad.LB
instance Control.Monad.State.Class.MonadState Lambdabot.Monad.IRCRWState Lambdabot.Monad.LB
instance Control.Monad.Catch.MonadThrow Lambdabot.Monad.LB


-- | Manage lambdabot's state files. There are three relevant directories:
--   
--   <ul>
--   <li>local: <tt>.<i>State</i></tt> (configurable, see
--   <a>outputDir</a>)</li>
--   <li>home: <tt>~<i>.lambdabot</i>State/</tt></li>
--   <li>data: relative to the data directory of the <tt>lambdabot</tt>
--   package.</li>
--   </ul>
--   
--   Files are stored locally if the directory exists; otherwise, in the
--   home directory. When reading a state file, and the file exists in the
--   data directory but nowhere else, then it is picked up from the data
--   directory.
module Lambdabot.File

-- | Locate state directory. Returns the local directory if it exists, and
--   the home directory otherwise.
stateDir :: LB FilePath

-- | Look for the file in the local, home, and data directories.
findLBFileForReading :: FilePath -> LB (Maybe FilePath)

-- | Return file name for writing state. The file will reside in the state
--   directory (<a>stateDir</a>), and <a>findLBFileForWriting</a> ensures
--   that the state directory exists.
findLBFileForWriting :: FilePath -> LB FilePath

-- | This returns the same file name as <a>findLBFileForWriting</a>. If the
--   file does not exist, it is either copied from the data (or home)
--   directory, if a copy is found there; otherwise, an empty file is
--   created instead.
findOrCreateLBFile :: FilePath -> LB String

-- | Try to find a pre-existing file, searching first in the local or home
--   directory (but not in the data directory)

-- | <i>Deprecated: Use <a>findLBFileForReading</a> or
--   <a>findLBFileForWriting</a> instead</i>
findLBFile :: FilePath -> LB (Maybe String)
outputDir :: Config FilePath


-- | Support for the LB (LambdaBot) monad
module Lambdabot.State
class MonadLB m => MonadLBState (m :: Type -> Type) where {
    type LBState (m :: Type -> Type);
}

-- | Update the module's private state. This is the preferred way of
--   changing the state. The state will be locked until the body returns.
--   The function is exception-safe, i.e. even if an error occurs or the
--   thread is killed (e.g. because it deadlocked and therefore exceeded
--   its time limit), the state from the last write operation will be
--   restored. If the writer escapes, calling it will have no observable
--   effect. <tt>withMS</tt> is not composable, in the sense that a readMS
--   from within the body will cause a dead-lock. However, all other
--   possibilies to access the state that came to my mind had even more
--   serious deficiencies such as being prone to race conditions or
--   semantic obscurities.
withMS :: MonadLBState m => (LBState m -> (LBState m -> m ()) -> m a) -> m a

-- | Read the module's private state.
readMS :: MonadLBState m => m (LBState m)

-- | Write the module's private state. Try to use withMS instead.
writeMS :: MonadLBState m => LBState m -> m ()

-- | Modify the module's private state.
modifyMS :: MonadLBState m => (LBState m -> LBState m) -> m ()

-- | This datatype allows modules to conviently maintain both global (i.e.
--   for all clients they're interacting with) and private state. It is
--   implemented on top of readMS/withMS.
--   
--   This simple implementation is linear in the number of private states
--   used.
data GlobalPrivate g p

-- | Creates a <tt>GlobalPrivate</tt> given the value of the global state.
--   No private state for clients will be created.
mkGlobalPrivate :: Int -> g -> GlobalPrivate g p

-- | Writes private state. For now, it locks everything.
withPS :: (MonadLBState m, LBState m ~ GlobalPrivate g p) => Nick -> (Maybe p -> (Maybe p -> LB ()) -> LB a) -> m a

-- | Reads private state.
readPS :: (MonadLBState m, LBState m ~ GlobalPrivate g p) => Nick -> m (Maybe p)
writePS :: (MonadLBState m, LBState m ~ GlobalPrivate g p) => Nick -> Maybe p -> m ()

-- | Writes global state. Locks everything
withGS :: (MonadLBState m, LBState m ~ GlobalPrivate g p) => (g -> (g -> m ()) -> m ()) -> m ()

-- | Reads global state.
readGS :: (MonadLBState m, LBState m ~ GlobalPrivate g p) => m g
writeGS :: (MonadLBState m, LBState m ~ GlobalPrivate g p) => g -> m ()

-- | Read it in
readGlobalState :: Module st -> String -> LB (Maybe st)

-- | Peristence: write the global state out
writeGlobalState :: ModuleT st LB ()
instance Lambdabot.State.MonadLBState m => Lambdabot.State.MonadLBState (Lambdabot.Command.Cmd m)
instance Lambdabot.Monad.MonadLB m => Lambdabot.State.MonadLBState (Lambdabot.Module.ModuleT st m)


-- | The guts of lambdabot.
--   
--   The LB/Lambdabot monad Generic server connection,disconnection The
--   module typeclass, type and operations on modules
module Lambdabot.Bot

-- | Register a module in the irc state
ircLoadModule :: String -> Module st -> LB ()

-- | Unregister a module's entry in the irc state
ircUnloadModule :: String -> LB ()

-- | Checks whether the given user has admin permissions
checkPrivs :: IrcMessage -> LB Bool

-- | Checks whether the given user is being ignored. Privileged users can't
--   be ignored.
checkIgnore :: IrcMessage -> LB Bool
ircCodepage :: String -> String -> LB ()
ircGetChannels :: LB [Nick]
ircQuit :: String -> String -> LB ()
ircReconnect :: String -> String -> LB ()

-- | Send a message to a channel/user, applying all output filters
ircPrivmsg :: Nick -> String -> LB ()
ircPrivmsg' :: Nick -> String -> LB ()

module Lambdabot.Plugin

-- | The Module type class.
data Module st
Module :: !Maybe (Serial st) -> !LB st -> !Bool -> !ModuleT st LB [Command (ModuleT st LB)] -> !ModuleT st LB () -> !ModuleT st LB () -> !String -> Cmd (ModuleT st LB) () -> Module st

-- | If the module wants its state to be saved, this function should return
--   a Serial.
--   
--   The default implementation returns Nothing.
[moduleSerialize] :: Module st -> !Maybe (Serial st)

-- | If the module maintains state, this method specifies the default state
--   (for example in case the state can't be read from a state).
--   
--   The default implementation returns an error and assumes the state is
--   never accessed.
[moduleDefState] :: Module st -> !LB st

-- | Is the module sticky? Sticky modules (as well as static ones) can't be
--   unloaded. By default, modules are not sticky.
[moduleSticky] :: Module st -> !Bool

-- | The commands the module listens to.
[moduleCmds] :: Module st -> !ModuleT st LB [Command (ModuleT st LB)]

-- | Initialize the module. The default implementation does nothing.
[moduleInit] :: Module st -> !ModuleT st LB ()

-- | Finalize the module. The default implementation does nothing.
[moduleExit] :: Module st -> !ModuleT st LB ()

-- | Process contextual input. A plugin that implements <a>contextual</a>
--   is able to respond to text not part of a normal command.
[contextual] :: Module st -> !String -> Cmd (ModuleT st LB) ()

-- | This transformer encodes the additional information a module might
--   need to access its name or its state.
data ModuleT st (m :: Type -> Type) a
newModule :: Module st

-- | The IRC Monad. The reader transformer holds information about the
--   connection to the IRC server.
--   
--   instances Monad, Functor, MonadIO, MonadState, MonadError
data LB a
class (MonadIO m, MonadBaseControl IO m, MonadConfig m, MonadLogging m, Applicative m, MonadFail m) => MonadLB (m :: Type -> Type)
lb :: MonadLB m => LB a -> m a
lim80 :: Monad m => m String -> Cmd m ()

-- | convenience, similar to ios but also cut output to channel to 80
--   characters usage: <tt>process _ _ to _ s = ios80 to (plugs s)</tt>
ios80 :: forall (m :: Type -> Type). MonadIO m => IO String -> Cmd m ()
data ChanName
mkCN :: Nick -> ChanName
getCN :: ChanName -> Nick

-- | The type of nicknames isolated from a message.
data Nick
Nick :: !String -> !String -> Nick

-- | The tag of the server this nick is on
[nTag] :: Nick -> !String

-- | The server-specific nickname of this nick
[nName] :: Nick -> !String

-- | Send a message to a channel/user, applying all output filters
ircPrivmsg :: Nick -> String -> LB ()
outputDir :: Config FilePath
commandPrefixes :: Config [String]
disabledCommands :: Config [String]
editDistanceLimit :: Config Int
enableInsults :: Config Bool
onStartupCmds :: Config [String]
dataDir :: Config FilePath
lbVersion :: Config Version
textWidth :: Config Int
uncaughtExceptionHandler :: Config DIH
replaceRootLogger :: Config Bool
lbRootLoggerPath :: Config [String]
consoleLogHandle :: Config Handle
consoleLogLevel :: Config Priority
consoleLogFormat :: Config String
data Command (m :: Type -> Type)
Command :: String -> [String] -> Bool -> Cmd m () -> (String -> Cmd m ()) -> Command (m :: Type -> Type)
[cmdName] :: Command (m :: Type -> Type) -> String
[aliases] :: Command (m :: Type -> Type) -> [String]
[privileged] :: Command (m :: Type -> Type) -> Bool
[help] :: Command (m :: Type -> Type) -> Cmd m ()
[process] :: Command (m :: Type -> Type) -> String -> Cmd m ()
cmdNames :: forall (m :: Type -> Type). Command m -> [String]
command :: String -> Command Identity
data Cmd (m :: Type -> Type) a
getCmdName :: forall (m :: Type -> Type). Monad m => Cmd m String
withMsg :: forall (m :: Type -> Type) t. Monad m => (forall a. Message a => a -> Cmd m t) -> Cmd m t
readNick :: forall (m :: Type -> Type). Monad m => String -> Cmd m Nick
showNick :: forall (m :: Type -> Type). Monad m => Nick -> Cmd m String
getServer :: forall (m :: Type -> Type). Monad m => Cmd m String
getSender :: forall (m :: Type -> Type). Monad m => Cmd m Nick
getTarget :: forall (m :: Type -> Type). Monad m => Cmd m Nick
getLambdabotName :: forall (m :: Type -> Type). Monad m => Cmd m Nick
say :: forall (m :: Type -> Type). Monad m => String -> Cmd m ()
data Serial s
Serial :: (s -> Maybe ByteString) -> (ByteString -> Maybe s) -> Serial s
[serialize] :: Serial s -> s -> Maybe ByteString
[deserialize] :: Serial s -> ByteString -> Maybe s

-- | Default `instance' for a Serial
stdSerial :: (Show s, Read s) => Serial s

-- | Serializes a <a>Map</a> type if both the key and the value are
--   instances of Read and Show. The serialization is done by converting
--   the map to and from lists. Results are saved line-wise, for better
--   editing and revision control.
mapSerial :: (Ord k, Show k, Show v, Read k, Read v) => Serial (Map k v)
mapPackedSerial :: Serial (Map ByteString ByteString)
assocListPackedSerial :: Serial [(ByteString, ByteString)]
mapListPackedSerial :: Serial (Map ByteString [ByteString])

-- | <a>readM</a> behaves like read, but catches failure in a monad. this
--   allocates a 20-30 M on startup...
readM :: (MonadFail m, Read a) => String -> m a
class Packable t
readPacked :: Packable t => ByteString -> t
showPacked :: Packable t => t -> ByteString
readOnly :: (ByteString -> b) -> Serial b


-- | Backward-compatibility shim for (de-)serializing <a>Nick</a>s using
--   the old <a>Read</a>/<a>Show</a> instances which gave freenode special
--   treatment.
module Lambdabot.Compat.FreenodeNick
newtype FreenodeNick
FreenodeNick :: Nick -> FreenodeNick
[getFreenodeNick] :: FreenodeNick -> Nick
freenodeNickMapSerial :: (Show v, Read v) => Serial (Map Nick v)
instance GHC.Classes.Eq Lambdabot.Compat.FreenodeNick.FreenodeNick
instance GHC.Classes.Ord Lambdabot.Compat.FreenodeNick.FreenodeNick
instance GHC.Internal.Read.Read Lambdabot.Compat.FreenodeNick.FreenodeNick
instance GHC.Internal.Show.Show Lambdabot.Compat.FreenodeNick.FreenodeNick

module Lambdabot.Plugin.Core
basePlugin :: Module (GlobalPrivate () ())
systemPlugin :: Module SystemState
offlineRCPlugin :: Module OfflineRCState
composePlugin :: Module ()
helpPlugin :: Module ()
morePlugin :: Module (GlobalPrivate () [String])
versionPlugin :: Module ()
corePlugins :: [String]
outputDir :: Config FilePath
commandPrefixes :: Config [String]
disabledCommands :: Config [String]
editDistanceLimit :: Config Int
enableInsults :: Config Bool
onStartupCmds :: Config [String]
dataDir :: Config FilePath
lbVersion :: Config Version
textWidth :: Config Int
uncaughtExceptionHandler :: Config DIH
replaceRootLogger :: Config Bool
lbRootLoggerPath :: Config [String]
consoleLogHandle :: Config Handle
consoleLogLevel :: Config Priority
consoleLogFormat :: Config String

module Lambdabot.Main
lambdabotVersion :: Version
data Config t

-- | A basic dependent sum type where the first component is a tag that
--   specifies the type of the second. For example, think of a GADT such
--   as:
--   
--   <pre>
--   data Tag a where
--      AString :: Tag String
--      AnInt   :: Tag Int
--      Rec     :: Tag (DSum Tag Identity)
--   </pre>
--   
--   Then we can write expressions where the RHS of
--   <tt>(<a>:=&gt;</a>)</tt> has different types depending on the
--   <tt>Tag</tt> constructor used. Here are some expressions of type
--   <tt>DSum Tag <tt>Identity</tt></tt>:
--   
--   <pre>
--   AString :=&gt; Identity "hello!"
--   AnInt   :=&gt; Identity 42
--   </pre>
--   
--   Often, the <tt>f</tt> we choose has an <a>Applicative</a> instance,
--   and we can use the helper function <tt>(<a>==&gt;</a>)</tt>. The
--   following expressions all have the type <tt>Applicative f =&gt; DSum
--   Tag f</tt>:
--   
--   <pre>
--   AString ==&gt; "hello!"
--   AnInt   ==&gt; 42
--   </pre>
--   
--   We can write functions that consume <tt>DSum Tag f</tt> values by
--   matching, such as:
--   
--   <pre>
--   toString :: DSum Tag Identity -&gt; String
--   toString (AString :=&gt; Identity str) = str
--   toString (AnInt   :=&gt; Identity int) = show int
--   toString (Rec     :=&gt; Identity sum) = toString sum
--   </pre>
--   
--   The <tt>(<a>:=&gt;</a>)</tt> constructor and <tt>(<a>==&gt;</a>)</tt>
--   helper are chosen to resemble the <tt>(key =&gt; value)</tt>
--   construction for dictionary entries in many dynamic languages. The
--   <tt>:=&gt;</tt> and <tt>==&gt;</tt> operators have very low precedence
--   and bind to the right, making repeated use of these operators behave
--   as you'd expect:
--   
--   <pre>
--   -- Parses as: Rec ==&gt; (AnInt ==&gt; (3 + 4))
--   -- Has type: Applicative f =&gt; DSum Tag f
--   Rec ==&gt; AnInt ==&gt; 3 + 4
--   </pre>
--   
--   The precedence of these operators is just above that of <a>$</a>, so
--   <tt>foo bar $ AString ==&gt; "eep"</tt> is equivalent to <tt>foo bar
--   (AString ==&gt; "eep")</tt>.
--   
--   To use the <a>Eq</a>, <a>Ord</a>, <a>Read</a>, and <a>Show</a>
--   instances for <tt><a>DSum</a> tag f</tt>, you will need an
--   <tt>ArgDict</tt> instance for your tag type. Use <a>deriveArgDict</a>
--   from the <tt>constraints-extras</tt> package to generate this
--   instance.
data DSum (tag :: k -> Type) (f :: k -> Type)
(:=>) :: !tag a -> f a -> DSum (tag :: k -> Type) (f :: k -> Type)
infixr 1 :=>

-- | Convenience helper. Uses <a>pure</a> to lift <tt>a</tt> into <tt>f
--   a</tt>.
(==>) :: forall (f :: Type -> Type) tag a. Applicative f => tag a -> a -> DSum tag f
infixr 1 ==>

-- | The Lambdabot entry point. Initialise plugins, connect, and run the
--   bot in the LB monad
--   
--   Also, handle any fatal exceptions (such as non-recoverable signals),
--   (i.e. print a message and exit). Non-fatal exceptions should be dealt
--   with in the mainLoop or further down.
lambdabotMain :: Modules -> [DSum Config Identity] -> IO ExitCode
type Modules = [(String, Some Module)]
modules :: [String] -> Q Exp

-- | Priorities are used to define how important a log message is. Users
--   can filter log messages based on priorities.
--   
--   These have their roots on the traditional syslog system. The standard
--   definitions are given below, but you are free to interpret them
--   however you like. They are listed here in ascending importance order.
data Priority

-- | Debug messages
DEBUG :: Priority

-- | Information
INFO :: Priority

-- | Normal runtime conditions
NOTICE :: Priority

-- | General Warnings
WARNING :: Priority

-- | General Errors
ERROR :: Priority

-- | Severe situations
CRITICAL :: Priority

-- | Take immediate action
ALERT :: Priority

-- | System is unusable
EMERGENCY :: Priority
