module SocketActivation.GetFileDescriptors where

import           Control.Monad             (Monad (return, (>>=)))
import           Data.Either               (Either)
import           Data.Function             ((.))
import           Data.Int                  (Int)
import           Data.List                 (take)
import           Numeric.Natural           (Natural)
import           Prelude                   (fromIntegral)
import           System.IO                 (IO)

import           SocketActivation.Concepts
import           SocketActivation.Env
import           SocketActivation.IO

-- | Get a list of file descriptors for the sockets.
getFileDescriptorList :: IO (Either Error [Fd])
getFileDescriptorList :: IO (Either Error [Fd])
getFileDescriptorList = IO' [Fd] -> IO (Either Error [Fd])
forall a. IO' a -> IO (Either Error a)
run (IO' Count
getCount IO' Count -> (Count -> IO' [Fd]) -> IO' [Fd]
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Count -> IO' [Fd]
enumerateFds)
  where
    getCount :: IO' Count
getCount = IO (Either Error Count) -> IO' Count
forall a. IO (Either Error a) -> IO' a
IO' (Env' Count => IO (Either Error Count)
forall a. Env' a => IO (Either Error a)
getEnv' @Count)
    enumerateFds :: Count -> IO' [Fd]
enumerateFds = [Fd] -> IO' [Fd]
forall (m :: * -> *) a. Monad m => a -> m a
return ([Fd] -> IO' [Fd]) -> (Count -> [Fd]) -> Count -> IO' [Fd]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Count -> [Fd]
fds

fds :: Count -> [Fd]
fds :: Count -> [Fd]
fds Count
n = Int -> [Fd] -> [Fd]
forall a. Int -> [a] -> [a]
take (Count -> Int
convert Count
n) [Fd
firstFd ..]
  where
    convert :: Count -> Int
convert = (Natural -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral :: Natural -> Int) (Natural -> Int) -> (Count -> Natural) -> Count -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Count -> Natural
countNat
    firstFd :: Fd
firstFd = CInt -> Fd
Fd CInt
3