module SocketActivation.GetByName where

import Essentials

import Control.Monad.IO.Class (MonadIO (liftIO))
import Data.Either (Either)
import Data.List (zip)
import Data.Map (Map)
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 forall a b. (a -> b) -> a -> b
$ forall a. IO (Either Error a) -> IO' a
IO' (forall a. Env' a => IO (Either Error a)
getEnv' @Names) forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> 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 forall a b. (a -> b) -> a -> b
$ IO' [(Name, Fd)]
entries forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList
  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
<$> forall a. IO (Either Error a) -> IO' a
IO' IO (Either Error [Name])
getNameList forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. IO (Either Error a) -> IO' a
IO' IO (Either Error [Fd])
getFileDescriptorList

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 (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList)
  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
<$> forall a. IO (Either Error a) -> IO' a
IO' IO (Either Error [Name])
getNameList forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. IO (Either Error a) -> IO' a
IO' IO (Either Error [Socket])
getSocketList

getSocketByName :: Name -> IO (Either Error Socket)
getSocketByName :: Name -> IO (Either Error Socket)
getSocketByName Name
name = forall a. IO' a -> IO (Either Error a)
run do
    Map Name Fd
m <- forall a. IO (Either Error a) -> IO' a
IO' IO (Either Error (Map Name Fd))
getFileDescriptorMap
    Fd
fd <- case forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup Name
name Map Name Fd
m of
        Maybe Fd
Nothing -> forall a. Error -> IO' a
throwError (Name -> [Name] -> Error
NoSuchName Name
name (forall k a. Map k a -> [k]
Map.keys Map Name Fd
m))
        Just Fd
x -> forall (f :: * -> *) a. Applicative f => a -> f a
pure Fd
x
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ Fd -> IO Socket
fdSocket Fd
fd