-- |
-- Module    : Where
-- Copyright : 2003 Shae Erisson
--
-- License:     lGPL
--
-- Slightly specialised version of Where for associating projects with their urls.
-- Code almost all copied.
module Lambdabot.Plugin.Reference.Where (wherePlugin) where

import Lambdabot.Plugin
import Lambdabot.Util
import qualified Data.ByteString.Char8 as P
import Data.Char
import qualified Data.Map as M

type WhereState         = M.Map P.ByteString P.ByteString
type WhereWriter        = WhereState -> Cmd Where ()
type Where              = ModuleT WhereState LB

wherePlugin :: Module (M.Map P.ByteString P.ByteString)
wherePlugin :: Module (Map ByteString ByteString)
wherePlugin = forall st. Module st
newModule
    { moduleDefState :: LB (Map ByteString ByteString)
moduleDefState  = forall (m :: * -> *) a. Monad m => a -> m a
return forall k a. Map k a
M.empty
    , moduleSerialize :: Maybe (Serial (Map ByteString ByteString))
moduleSerialize = forall a. a -> Maybe a
Just Serial (Map ByteString ByteString)
mapPackedSerial

    , moduleCmds :: ModuleT (Map ByteString ByteString) LB [Command Where]
moduleCmds = forall (m :: * -> *) a. Monad m => a -> m a
return
        [ (String -> Command Identity
command String
"where")
            { help :: Cmd Where ()
help = forall (m :: * -> *). Monad m => String -> Cmd m ()
say String
"where <key>. Return element associated with key"
            , process :: String -> Cmd Where ()
process = String -> String -> Cmd Where ()
doCmd String
"where"
            }
        , (String -> Command Identity
command String
"url")
            { help :: Cmd Where ()
help = forall (m :: * -> *). Monad m => String -> Cmd m ()
say String
"url <key>. Return element associated with key"
            , process :: String -> Cmd Where ()
process = String -> String -> Cmd Where ()
doCmd String
"url"
            }
        , (String -> Command Identity
command String
"what")
            { help :: Cmd Where ()
help = forall (m :: * -> *). Monad m => String -> Cmd m ()
say String
"what <key>. Return element associated with key"
            , process :: String -> Cmd Where ()
process = String -> String -> Cmd Where ()
doCmd String
"what"
            }
        , (String -> Command Identity
command String
"where+")
            { help :: Cmd Where ()
help = forall (m :: * -> *). Monad m => String -> Cmd m ()
say String
"where+ <key> <elem>. Define an association"
            , process :: String -> Cmd Where ()
process = String -> String -> Cmd Where ()
doCmd String
"where+"
            }
        ]
    }

doCmd :: String -> String -> Cmd Where ()
doCmd :: String -> String -> Cmd Where ()
doCmd String
cmd String
rest = (forall (m :: * -> *). Monad m => String -> Cmd m ()
say forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<<) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *) a.
MonadLBState m =>
(LBState m -> (LBState m -> m ()) -> m a) -> m a
withMS forall a b. (a -> b) -> a -> b
$ \Map ByteString ByteString
factFM WhereWriter
writer ->
    case String -> [String]
words String
rest of
        []         -> forall (m :: * -> *) a. Monad m => a -> m a
return String
"@where <key>, return element associated with key"
        (String
fact:[String]
dat) -> Map ByteString ByteString
-> WhereWriter -> String -> String -> String -> Cmd Where String
processCommand Map ByteString ByteString
factFM WhereWriter
writer
                            (forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
toLower String
fact) String
cmd ([String] -> String
unwords [String]
dat)

------------------------------------------------------------------------

processCommand :: WhereState -> WhereWriter
               -> String -> String -> String -> Cmd Where String

processCommand :: Map ByteString ByteString
-> WhereWriter -> String -> String -> String -> Cmd Where String
processCommand Map ByteString ByteString
factFM WhereWriter
writer String
fact String
cmd String
dat = case String
cmd of
        String
"where"     -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Map ByteString ByteString -> String -> String
getWhere Map ByteString ByteString
factFM String
fact
        String
"what"      -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Map ByteString ByteString -> String -> String
getWhere Map ByteString ByteString
factFM String
fact -- an alias
        String
"url"       -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Map ByteString ByteString -> String -> String
getWhere Map ByteString ByteString
factFM String
fact -- an alias
        String
"where+"    -> Bool
-> Map ByteString ByteString
-> WhereWriter
-> String
-> String
-> Cmd Where String
updateWhere Bool
True Map ByteString ByteString
factFM WhereWriter
writer String
fact String
dat
        String
_           -> forall (m :: * -> *) a. Monad m => a -> m a
return String
"Unknown command."

getWhere :: WhereState -> String -> String
getWhere :: Map ByteString ByteString -> String -> String
getWhere Map ByteString ByteString
fm String
fact =
    case forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup (String -> ByteString
P.pack String
fact) Map ByteString ByteString
fm of
        Maybe ByteString
Nothing -> String
"I know nothing about " forall a. [a] -> [a] -> [a]
++ String
fact forall a. [a] -> [a] -> [a]
++ String
"."
        Just ByteString
x  -> ByteString -> String
P.unpack ByteString
x

updateWhere :: Bool -> WhereState -> WhereWriter -> String -> String -> Cmd Where String
updateWhere :: Bool
-> Map ByteString ByteString
-> WhereWriter
-> String
-> String
-> Cmd Where String
updateWhere Bool
_guard Map ByteString ByteString
factFM WhereWriter
writer String
fact String
dat
    | forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
dat = do
        WhereWriter
writer forall a b. (a -> b) -> a -> b
$ forall k a. Ord k => k -> Map k a -> Map k a
M.delete (String -> ByteString
P.pack String
fact) Map ByteString ByteString
factFM
        forall (m :: * -> *) a. Monad m => a -> m a
return String
"It is forgotten."
    | Bool
otherwise = do
        WhereWriter
writer forall a b. (a -> b) -> a -> b
$ forall k a. Ord k => k -> a -> Map k a -> Map k a
M.insert (String -> ByteString
P.pack String
fact) (String -> ByteString
P.pack String
dat) Map ByteString ByteString
factFM
        forall (m :: * -> *). MonadIO m => m String
randomSuccessMsg