{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE Strict     #-}

module Foreign.Erlang.Mailbox
    ( Mailbox(..)
    , deliverLink
    , deliverSend
    , deliverExit
    , deliverUnlink
    , deliverRegSend
    , deliverGroupLeader
    , deliverExit2
    , receive
    ) where

import           Foreign.Erlang.Term
import           Control.Concurrent.STM

data Mailbox = MkMailbox { Mailbox -> Pid
self     :: Pid
                         , Mailbox -> TQueue Term
msgQueue :: TQueue Term
                         }

deliverLink :: Mailbox -> Pid -> IO ()
deliverLink :: Mailbox -> Pid -> IO ()
deliverLink = Mailbox -> Pid -> IO ()
forall a. HasCallStack => a
undefined

deliverSend :: Mailbox -> Term -> IO ()
deliverSend :: Mailbox -> Term -> IO ()
deliverSend MkMailbox{TQueue Term
msgQueue :: TQueue Term
msgQueue :: Mailbox -> TQueue Term
msgQueue} =
    STM () -> IO ()
forall a. STM a -> IO a
atomically (STM () -> IO ()) -> (Term -> STM ()) -> Term -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TQueue Term -> Term -> STM ()
forall a. TQueue a -> a -> STM ()
writeTQueue TQueue Term
msgQueue

deliverExit :: Mailbox -> Pid -> Term -> IO ()
deliverExit :: Mailbox -> Pid -> Term -> IO ()
deliverExit =
    Mailbox -> Pid -> Term -> IO ()
forall a. HasCallStack => a
undefined

deliverUnlink :: Mailbox -> Pid -> IO ()
deliverUnlink :: Mailbox -> Pid -> IO ()
deliverUnlink =
    Mailbox -> Pid -> IO ()
forall a. HasCallStack => a
undefined

deliverRegSend :: Mailbox -> Pid -> Term -> IO ()
deliverRegSend :: Mailbox -> Pid -> Term -> IO ()
deliverRegSend MkMailbox{TQueue Term
msgQueue :: TQueue Term
msgQueue :: Mailbox -> TQueue Term
msgQueue} Pid
_fromPid Term
message =
    STM () -> IO ()
forall a. STM a -> IO a
atomically (STM () -> IO ()) -> STM () -> IO ()
forall a b. (a -> b) -> a -> b
$ TQueue Term -> Term -> STM ()
forall a. TQueue a -> a -> STM ()
writeTQueue TQueue Term
msgQueue Term
message

deliverGroupLeader :: Mailbox -> Pid -> IO ()
deliverGroupLeader :: Mailbox -> Pid -> IO ()
deliverGroupLeader =
    Mailbox -> Pid -> IO ()
forall a. HasCallStack => a
undefined

deliverExit2 :: Mailbox -> Pid -> Term -> IO ()
deliverExit2 :: Mailbox -> Pid -> Term -> IO ()
deliverExit2 =
    Mailbox -> Pid -> Term -> IO ()
forall a. HasCallStack => a
undefined

receive :: Mailbox -> IO Term
receive :: Mailbox -> IO Term
receive MkMailbox{TQueue Term
msgQueue :: TQueue Term
msgQueue :: Mailbox -> TQueue Term
msgQueue} =
    STM Term -> IO Term
forall a. STM a -> IO a
atomically (TQueue Term -> STM Term
forall a. TQueue a -> STM a
readTQueue TQueue Term
msgQueue)