doPart ::
  UserInfo   {- ^ user information -} ->
  Identifier {- ^ channel          -} ->
  ByteString {- ^ part reason      -} ->
  IrcConnection -> Logic IrcConnection
doPart who chan reason conn =
  do stamp <- getStamp
     let mesg = defaultIrcMessage
                { _mesgType = PartMsgType (asUtf8 reason)
                , _mesgSender = who
                , _mesgStamp = stamp
                }
         removeUser = set (chanUsers . at (userNick who)) Nothing

     conn1 <- fmap (over (connChannels . ix chan) removeUser)
                   (recordMessage mesg chan conn)

     let stillKnown = has (connChannels . folded . chanUsers . ix (userNick who))
                          conn1

         conn2 | stillKnown = conn1
               | otherwise  = set (connUsers . at (userNick who)) Nothing conn1

         conn3 | isMyNick (userNick who) conn =
                    set (connChannels . at chan) Nothing conn2
               | otherwise = conn2

     return conn3

-- | Update an 'IrcConnection' when a user is kicked from a channel.
doPart ::
  UserInfo   {- ^ user information -} ->
  Identifier {- ^ channel          -} ->
  ByteString {- ^ part reason      -} ->
  IrcConnection -> Logic IrcConnection
doPart who chan reason conn =
  do stamp <- getStamp
     let mesg = defaultIrcMessage
                { _mesgType = PartMsgType (asUtf8 reason)
                , _mesgSender = who
                , _mesgStamp = stamp
                }
         removeUser = set (chanUsers . at (userNick who)) Nothing

     conn1 <- fmap (over (connChannels . ix chan) removeUser)
                   (recordMessage mesg chan conn)

     let stillKnown = has (connChannels . folded . chanUsers . ix (userNick who))
                          conn1

         conn2 | stillKnown = conn1
               | otherwise  = set (connUsers . at (userNick who)) Nothing conn1

         conn3 | isMyNick (userNick who) conn =
                    set (connChannels . at chan) Nothing conn2
               | otherwise = conn2

     return conn3

-- | Update an 'IrcConnection' when a user is kicked from a channel.
doPart who chan reason conn =
  do stamp <- getStamp
     let mesg = defaultIrcMessage
                { _mesgType = PartMsgType (asUtf8 reason)
                , _mesgSender = who
                , _mesgStamp = stamp
                }
         removeUser = set (chanUsers . at (userNick who)) Nothing

     conn1 <- fmap (over (connChannels . ix chan) removeUser)
                   (recordMessage mesg chan conn)

     let stillKnown = has (connChannels . folded . chanUsers . ix (userNick who))
                          conn1

         conn2 | stillKnown = conn1
               | otherwise  = set (connUsers . at (userNick who)) Nothing conn1

         conn3 | isMyNick (userNick who) conn =
                    set (connChannels . at chan) Nothing conn2
               | otherwise = conn2

     return conn3

-- | Update an 'IrcConnection' when a user is kicked from a channel.