module SocketActivation.GetByName where

import           Control.Applicative                 (Applicative ((<*>)),
                                                      (<$>))
import           Control.Monad                       (Monad (return, (>>=)))
import           Control.Monad.IO.Class              (MonadIO (liftIO))
import           Data.Either                         (Either)
import           Data.Function                       ((.))
import           Data.List                           (zip)
import           Data.Map                            (Map)
import           Data.Maybe                          (maybe)
import           System.IO                           (IO)

import qualified Data.Map                            as Map

import           SocketActivation.Concepts
import           SocketActivation.Env
import           SocketActivation.GetFileDescriptors
import           SocketActivation.GetSockets
import           SocketActivation.IO

getNameList :: IO (Either Error [Name])
getNameList :: IO (Either Error [Name])
getNameList = IO' [Name] -> IO (Either Error [Name])
forall a. IO' a -> IO (Either Error a)
run (IO' Names
getNames IO' Names -> (Names -> IO' [Name]) -> IO' [Name]
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Names -> IO' [Name]
unwrap)
  where
    getNames :: IO' Names
getNames = IO (Either Error Names) -> IO' Names
forall a. IO (Either Error a) -> IO' a
IO' (Env' Names => IO (Either Error Names)
forall a. Env' a => IO (Either Error a)
getEnv' @Names)
    unwrap :: Names -> IO' [Name]
unwrap = [Name] -> IO' [Name]
forall (m :: * -> *) a. Monad m => a -> m a
return ([Name] -> IO' [Name]) -> (Names -> [Name]) -> Names -> IO' [Name]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Names -> [Name]
namesList

getFileDescriptorMap :: IO (Either Error (Map Name Fd))
getFileDescriptorMap :: IO (Either Error (Map Name Fd))
getFileDescriptorMap = IO' (Map Name Fd) -> IO (Either Error (Map Name Fd))
forall a. IO' a -> IO (Either Error a)
run (IO' [(Name, Fd)]
entries IO' [(Name, Fd)]
-> ([(Name, Fd)] -> IO' (Map Name Fd)) -> IO' (Map Name Fd)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= [(Name, Fd)] -> IO' (Map Name Fd)
forall a. [(Name, a)] -> IO' (Map Name a)
toMap)
  where
    entries :: IO' [(Name, Fd)]
entries = [Name] -> [Fd] -> [(Name, Fd)]
forall a b. [a] -> [b] -> [(a, b)]
zip ([Name] -> [Fd] -> [(Name, Fd)])
-> IO' [Name] -> IO' ([Fd] -> [(Name, Fd)])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IO' [Name]
keys IO' ([Fd] -> [(Name, Fd)]) -> IO' [Fd] -> IO' [(Name, Fd)]
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> IO' [Fd]
values
    keys :: IO' [Name]
keys = IO (Either Error [Name]) -> IO' [Name]
forall a. IO (Either Error a) -> IO' a
IO' IO (Either Error [Name])
getNameList
    values :: IO' [Fd]
values = IO (Either Error [Fd]) -> IO' [Fd]
forall a. IO (Either Error a) -> IO' a
IO' IO (Either Error [Fd])
getFileDescriptorList
    toMap :: [(Name, a)] -> IO' (Map Name a)
toMap = Map Name a -> IO' (Map Name a)
forall (m :: * -> *) a. Monad m => a -> m a
return (Map Name a -> IO' (Map Name a))
-> ([(Name, a)] -> Map Name a) -> [(Name, a)] -> IO' (Map Name a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(Name, a)] -> Map Name a
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList

getSocketMap :: IO (Either Error (Map Name Socket))
getSocketMap :: IO (Either Error (Map Name Socket))
getSocketMap = IO' (Map Name Socket) -> IO (Either Error (Map Name Socket))
forall a. IO' a -> IO (Either Error a)
run (IO' [(Name, Socket)]
entries IO' [(Name, Socket)]
-> ([(Name, Socket)] -> IO' (Map Name Socket))
-> IO' (Map Name Socket)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= [(Name, Socket)] -> IO' (Map Name Socket)
forall a. [(Name, a)] -> IO' (Map Name a)
toMap)
  where
    entries :: IO' [(Name, Socket)]
entries = [Name] -> [Socket] -> [(Name, Socket)]
forall a b. [a] -> [b] -> [(a, b)]
zip ([Name] -> [Socket] -> [(Name, Socket)])
-> IO' [Name] -> IO' ([Socket] -> [(Name, Socket)])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IO' [Name]
keys IO' ([Socket] -> [(Name, Socket)])
-> IO' [Socket] -> IO' [(Name, Socket)]
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> IO' [Socket]
values
    keys :: IO' [Name]
keys = IO (Either Error [Name]) -> IO' [Name]
forall a. IO (Either Error a) -> IO' a
IO' IO (Either Error [Name])
getNameList
    values :: IO' [Socket]
values = IO (Either Error [Socket]) -> IO' [Socket]
forall a. IO (Either Error a) -> IO' a
IO' IO (Either Error [Socket])
getSocketList
    toMap :: [(Name, a)] -> IO' (Map Name a)
toMap = Map Name a -> IO' (Map Name a)
forall (m :: * -> *) a. Monad m => a -> m a
return (Map Name a -> IO' (Map Name a))
-> ([(Name, a)] -> Map Name a) -> [(Name, a)] -> IO' (Map Name a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(Name, a)] -> Map Name a
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList

getSocketByName :: Name -> IO (Either Error Socket)
getSocketByName :: Name -> IO (Either Error Socket)
getSocketByName Name
name = IO' Socket -> IO (Either Error Socket)
forall a. IO' a -> IO (Either Error a)
run (IO' (Map Name Fd)
getMap IO' (Map Name Fd) -> (Map Name Fd -> IO' Fd) -> IO' Fd
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Map Name Fd -> IO' Fd
forall a. Map Name a -> IO' a
findFd IO' Fd -> (Fd -> IO' Socket) -> IO' Socket
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Fd -> IO' Socket
convertToSocket)
  where
    getMap :: IO' (Map Name Fd)
getMap = IO (Either Error (Map Name Fd)) -> IO' (Map Name Fd)
forall a. IO (Either Error a) -> IO' a
IO' IO (Either Error (Map Name Fd))
getFileDescriptorMap
    findFd :: Map Name a -> IO' a
findFd = IO' a -> (a -> IO' a) -> Maybe a -> IO' a
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (Error -> IO' a
forall a. Error -> IO' a
throwError (Name -> Error
NoSuchName Name
name)) a -> IO' a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe a -> IO' a)
-> (Map Name a -> Maybe a) -> Map Name a -> IO' a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Name -> Map Name a -> Maybe a
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup Name
name
    convertToSocket :: Fd -> IO' Socket
convertToSocket = IO Socket -> IO' Socket
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Socket -> IO' Socket) -> (Fd -> IO Socket) -> Fd -> IO' Socket
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Fd -> IO Socket
fdSocket