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
    (Socket, Fd, Error (NoSuchName), Names (namesList), Name)
import SocketActivation.Env (getEnv')
import SocketActivation.GetFileDescriptors (getFileDescriptorList)
import SocketActivation.GetSockets (getSocketList, fdSocket)
import SocketActivation.IO (IO' (IO', run), throwError)

getNameList :: IO (Either Error [Name])
getNameList :: IO (Either Error [Name])
getNameList = forall a. IO' a -> IO (Either Error a)
run (IO' Names
getNames forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Names -> IO' [Name]
unwrap)
  where
    getNames :: IO' Names
getNames = forall a. IO (Either Error a) -> IO' a
IO' (forall a. Env' a => IO (Either Error a)
getEnv' @Names)
    unwrap :: Names -> IO' [Name]
unwrap = forall (m :: * -> *) a. Monad m => a -> m a
return 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 = forall a. IO' a -> IO (Either Error a)
run (IO' [(Name, Fd)]
entries forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall {a}. [(Name, a)] -> IO' (Map Name a)
toMap)
  where
    entries :: IO' [(Name, Fd)]
entries = forall a b. [a] -> [b] -> [(a, b)]
zip forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IO' [Name]
keys forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> IO' [Fd]
values
    keys :: IO' [Name]
keys = forall a. IO (Either Error a) -> IO' a
IO' IO (Either Error [Name])
getNameList
    values :: IO' [Fd]
values = forall a. IO (Either Error a) -> IO' a
IO' IO (Either Error [Fd])
getFileDescriptorList
    toMap :: [(Name, a)] -> IO' (Map Name a)
toMap = forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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 = forall a. IO' a -> IO (Either Error a)
run (IO' [(Name, Socket)]
entries forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall {a}. [(Name, a)] -> IO' (Map Name a)
toMap)
  where
    entries :: IO' [(Name, Socket)]
entries = forall a b. [a] -> [b] -> [(a, b)]
zip forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IO' [Name]
keys forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> IO' [Socket]
values
    keys :: IO' [Name]
keys = forall a. IO (Either Error a) -> IO' a
IO' IO (Either Error [Name])
getNameList
    values :: IO' [Socket]
values = forall a. IO (Either Error a) -> IO' a
IO' IO (Either Error [Socket])
getSocketList
    toMap :: [(Name, a)] -> IO' (Map Name a)
toMap = forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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 = forall a. IO' a -> IO (Either Error a)
run (IO' (Map Name Fd)
getMap forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall {a}. Map Name a -> IO' a
findFd forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Fd -> IO' Socket
convertToSocket)
  where
    getMap :: IO' (Map Name Fd)
getMap = forall a. IO (Either Error a) -> IO' a
IO' IO (Either Error (Map Name Fd))
getFileDescriptorMap
    findFd :: Map Name a -> IO' a
findFd = forall b a. b -> (a -> b) -> Maybe a -> b
maybe (forall a. Error -> IO' a
throwError (Name -> Error
NoSuchName Name
name)) forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup Name
name
    convertToSocket :: Fd -> IO' Socket
convertToSocket = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. Fd -> IO Socket
fdSocket