{-# LANGUAGE OverloadedStrings #-}
module Network.IRC.Bot.Part.Channels where

import Control.Concurrent.STM (atomically)
import Control.Concurrent.STM.TVar (TVar, newTVar, readTVar, writeTVar)
import Control.Monad.Trans (MonadIO(liftIO))
import Data.Set (Set, insert, toList)
import Data.ByteString (ByteString)
import Network.IRC (Message(..), joinChan)
import Network.IRC.Bot.BotMonad (BotMonad(..))
import Network.IRC.Bot.Log (LogLevel(..))

initChannelsPart :: (BotMonad m) => Set ByteString -> IO (TVar (Set ByteString), m ())
initChannelsPart :: forall (m :: * -> *).
BotMonad m =>
Set ByteString -> IO (TVar (Set ByteString), m ())
initChannelsPart Set ByteString
chans =
    do TVar (Set ByteString)
channels <- forall a. STM a -> IO a
atomically forall a b. (a -> b) -> a -> b
$ forall a. a -> STM (TVar a)
newTVar Set ByteString
chans
       forall (m :: * -> *) a. Monad m => a -> m a
return (TVar (Set ByteString)
channels, forall (m :: * -> *). BotMonad m => TVar (Set ByteString) -> m ()
channelsPart TVar (Set ByteString)
channels)

channelsPart :: (BotMonad m) => TVar (Set ByteString) -> m ()
channelsPart :: forall (m :: * -> *). BotMonad m => TVar (Set ByteString) -> m ()
channelsPart TVar (Set ByteString)
channels =
    do Message
msg <- forall (m :: * -> *). BotMonad m => m Message
askMessage
       let cmd :: ByteString
cmd = Message -> ByteString
msg_command Message
msg
       case ByteString
cmd of
         ByteString
"005" -> do Set ByteString
chans <- forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a. STM a -> IO a
atomically forall a b. (a -> b) -> a -> b
$ forall a. TVar a -> STM a
readTVar TVar (Set ByteString)
channels
                     forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ forall (m :: * -> *). BotMonad m => ByteString -> m ()
doJoin (forall a. Set a -> [a]
toList Set ByteString
chans)
         ByteString
_ -> forall (m :: * -> *) a. Monad m => a -> m a
return ()
    where
      doJoin :: (BotMonad m) => ByteString -> m ()
      doJoin :: forall (m :: * -> *). BotMonad m => ByteString -> m ()
doJoin ByteString
chan =
          do forall (m :: * -> *). BotMonad m => Message -> m ()
sendMessage (ByteString -> Message
joinChan ByteString
chan)
             forall (m :: * -> *). BotMonad m => LogLevel -> ByteString -> m ()
logM LogLevel
Normal forall a b. (a -> b) -> a -> b
$ ByteString
"Joining room " forall a. Semigroup a => a -> a -> a
<> ByteString
chan

joinChannel :: (BotMonad m) => ByteString -> TVar (Set ByteString) -> m ()
joinChannel :: forall (m :: * -> *).
BotMonad m =>
ByteString -> TVar (Set ByteString) -> m ()
joinChannel ByteString
chan TVar (Set ByteString)
channels =
    do forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a. STM a -> IO a
atomically forall a b. (a -> b) -> a -> b
$
           do Set ByteString
cs <- forall a. TVar a -> STM a
readTVar TVar (Set ByteString)
channels
              forall a. TVar a -> a -> STM ()
writeTVar TVar (Set ByteString)
channels (forall a. Ord a => a -> Set a -> Set a
insert ByteString
chan Set ByteString
cs)
       forall (m :: * -> *). BotMonad m => Message -> m ()
sendMessage (ByteString -> Message
joinChan ByteString
chan)