{-# Language BlockArguments, TemplateHaskell, OverloadedStrings, BangPatterns #-}

{-|
Module      : Client.State.Target
Description : IRC message routing
Copyright   : (c) Eric Mertens, 2016
License     : ISC
Maintainer  : emertens@gmail.com

This module contains glirc-specific overrides of the message routing provided by irc-core.
-}

module Client.State.Target
  (
    MessageTarget(..)
  , msgTarget
  ) where

import qualified Data.Text as Text
import           Irc.Codes
import           Irc.Identifier (Identifier, mkId)
import           Irc.Message (IrcMsg(..), srcUser)
import qualified Irc.Message as Msg
import           Irc.UserInfo (userNick, parseUserInfo)

data MessageTarget
  = TargetDrop                 -- ^ Do not record the message anywhere.
  | TargetUser     !Identifier -- ^ Record the message in all channels/PMs shared with the user.
  | TargetWindow   !Identifier -- ^ Directed message to channel or from user.
  | TargetExisting !Identifier -- ^ As @TargetWindow@ but only for existing windows.
  | TargetNetwork              -- ^ Record the message in the network window.

msgTarget :: Identifier -> IrcMsg -> MessageTarget
msgTarget :: Identifier -> IrcMsg -> MessageTarget
msgTarget Identifier
nick IrcMsg
msg =
  case IrcMsg
msg of
    Authenticate{}  -> MessageTarget
TargetDrop
    BatchStart{}    -> MessageTarget
TargetDrop
    BatchEnd{}      -> MessageTarget
TargetDrop
    Ping{}          -> MessageTarget
TargetDrop
    Pong{}          -> MessageTarget
TargetDrop
    Away Source
user Maybe Text
_     -> Identifier -> MessageTarget
TargetExisting (UserInfo -> Identifier
userNick (Source -> UserInfo
srcUser Source
user))
    Invite Source
_ Identifier
_ Identifier
chan -> Identifier -> MessageTarget
TargetWindow Identifier
chan
    Reply Text
_ ReplyCode
RPL_MONONLINE [Text
_,Text
who]  | [Text
who'] <- (Char -> Bool) -> Text -> [Text]
Text.split (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
==Char
',') Text
who ->
      Identifier -> MessageTarget
TargetWindow (UserInfo -> Identifier
userNick (UserInfo -> Identifier) -> UserInfo -> Identifier
forall a b. (a -> b) -> a -> b
$ Text -> UserInfo
parseUserInfo Text
who')
    Reply Text
_ ReplyCode
RPL_MONOFFLINE [Text
_,Text
who] | [Text
who'] <- (Char -> Bool) -> Text -> [Text]
Text.split (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
==Char
',') Text
who ->
      Identifier -> MessageTarget
TargetWindow (Text -> Identifier
mkId Text
who')
    Reply Text
_ ReplyCode
RPL_WHOSPCRPL [Text
_,Text
"616",Text
_,Text
_,Text
_,Text
_] -> MessageTarget
TargetDrop
    IrcMsg
_ -> case Identifier -> IrcMsg -> MessageTarget
Msg.msgTarget Identifier
nick IrcMsg
msg of
      Msg.TargetUser Identifier
id'   -> Identifier -> MessageTarget
TargetUser Identifier
id'
      Msg.TargetWindow Identifier
id' -> Identifier -> MessageTarget
TargetWindow Identifier
id'
      MessageTarget
Msg.TargetNetwork    -> MessageTarget
TargetNetwork