module SocketActivation.Concepts
  ( Recipient (..)
  , ProcessID
  , Count (..)
  , Name (..)
  , Names (..)
  , VarName (..)
  , Fd (..)
  , Socket
  , Error (..)
  ) where

import           Control.Exception  (Exception)
import           Data.String        (IsString)
import           Data.Text          (Text)
import           Numeric.Natural    (Natural)
import           Prelude            (Bounded, Enum, Eq, Ord, Show)

import           Network.Socket     (Socket)
import           System.Posix.Types (Fd (..), ProcessID)

-- | The ID of the process to whom systemd has given the sockets. A process should not use sockets that are intended for someone else, so we should always check that this matches our own PID before proceeding doing anything with the sockets.
newtype Recipient = RecipientPID { Recipient -> ProcessID
recipientPID :: ProcessID }
    deriving stock (Recipient -> Recipient -> Bool
(Recipient -> Recipient -> Bool)
-> (Recipient -> Recipient -> Bool) -> Eq Recipient
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Recipient -> Recipient -> Bool
$c/= :: Recipient -> Recipient -> Bool
== :: Recipient -> Recipient -> Bool
$c== :: Recipient -> Recipient -> Bool
Eq, Int -> Recipient -> ShowS
[Recipient] -> ShowS
Recipient -> String
(Int -> Recipient -> ShowS)
-> (Recipient -> String)
-> ([Recipient] -> ShowS)
-> Show Recipient
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Recipient] -> ShowS
$cshowList :: [Recipient] -> ShowS
show :: Recipient -> String
$cshow :: Recipient -> String
showsPrec :: Int -> Recipient -> ShowS
$cshowsPrec :: Int -> Recipient -> ShowS
Show)

-- | The number of sockets that systemd has given the process.
newtype Count = CountNat { Count -> Natural
countNat :: Natural }
    deriving stock (Count -> Count -> Bool
(Count -> Count -> Bool) -> (Count -> Count -> Bool) -> Eq Count
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Count -> Count -> Bool
$c/= :: Count -> Count -> Bool
== :: Count -> Count -> Bool
$c== :: Count -> Count -> Bool
Eq, Int -> Count -> ShowS
[Count] -> ShowS
Count -> String
(Int -> Count -> ShowS)
-> (Count -> String) -> ([Count] -> ShowS) -> Show Count
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Count] -> ShowS
$cshowList :: [Count] -> ShowS
show :: Count -> String
$cshow :: Count -> String
showsPrec :: Int -> Count -> ShowS
$cshowsPrec :: Int -> Count -> ShowS
Show)

-- | The name of a socket, corresponding to the socket's FileDescriptorName in the systemd config.
newtype Name = NameText { Name -> Text
nameText :: Text }
    deriving stock (Name -> Name -> Bool
(Name -> Name -> Bool) -> (Name -> Name -> Bool) -> Eq Name
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Name -> Name -> Bool
$c/= :: Name -> Name -> Bool
== :: Name -> Name -> Bool
$c== :: Name -> Name -> Bool
Eq, Eq Name
Eq Name
-> (Name -> Name -> Ordering)
-> (Name -> Name -> Bool)
-> (Name -> Name -> Bool)
-> (Name -> Name -> Bool)
-> (Name -> Name -> Bool)
-> (Name -> Name -> Name)
-> (Name -> Name -> Name)
-> Ord Name
Name -> Name -> Bool
Name -> Name -> Ordering
Name -> Name -> Name
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Name -> Name -> Name
$cmin :: Name -> Name -> Name
max :: Name -> Name -> Name
$cmax :: Name -> Name -> Name
>= :: Name -> Name -> Bool
$c>= :: Name -> Name -> Bool
> :: Name -> Name -> Bool
$c> :: Name -> Name -> Bool
<= :: Name -> Name -> Bool
$c<= :: Name -> Name -> Bool
< :: Name -> Name -> Bool
$c< :: Name -> Name -> Bool
compare :: Name -> Name -> Ordering
$ccompare :: Name -> Name -> Ordering
$cp1Ord :: Eq Name
Ord, Int -> Name -> ShowS
[Name] -> ShowS
Name -> String
(Int -> Name -> ShowS)
-> (Name -> String) -> ([Name] -> ShowS) -> Show Name
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Name] -> ShowS
$cshowList :: [Name] -> ShowS
show :: Name -> String
$cshow :: Name -> String
showsPrec :: Int -> Name -> ShowS
$cshowsPrec :: Int -> Name -> ShowS
Show)
    deriving newtype String -> Name
(String -> Name) -> IsString Name
forall a. (String -> a) -> IsString a
fromString :: String -> Name
$cfromString :: String -> Name
IsString

-- | The names of the sockets that we have been given, corresponding to the FileDescriptorName of each systemd socket.
newtype Names = NamesList { Names -> [Name]
namesList :: [Name] }
    deriving stock (Names -> Names -> Bool
(Names -> Names -> Bool) -> (Names -> Names -> Bool) -> Eq Names
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Names -> Names -> Bool
$c/= :: Names -> Names -> Bool
== :: Names -> Names -> Bool
$c== :: Names -> Names -> Bool
Eq, Int -> Names -> ShowS
[Names] -> ShowS
Names -> String
(Int -> Names -> ShowS)
-> (Names -> String) -> ([Names] -> ShowS) -> Show Names
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Names] -> ShowS
$cshowList :: [Names] -> ShowS
show :: Names -> String
$cshow :: Names -> String
showsPrec :: Int -> Names -> ShowS
$cshowsPrec :: Int -> Names -> ShowS
Show)

data VarName = LISTEN_PID | LISTEN_FDS | LISTEN_FDNAMES
    deriving stock (VarName -> VarName -> Bool
(VarName -> VarName -> Bool)
-> (VarName -> VarName -> Bool) -> Eq VarName
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: VarName -> VarName -> Bool
$c/= :: VarName -> VarName -> Bool
== :: VarName -> VarName -> Bool
$c== :: VarName -> VarName -> Bool
Eq, Int -> VarName -> ShowS
[VarName] -> ShowS
VarName -> String
(Int -> VarName -> ShowS)
-> (VarName -> String) -> ([VarName] -> ShowS) -> Show VarName
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [VarName] -> ShowS
$cshowList :: [VarName] -> ShowS
show :: VarName -> String
$cshow :: VarName -> String
showsPrec :: Int -> VarName -> ShowS
$cshowsPrec :: Int -> VarName -> ShowS
Show, Int -> VarName
VarName -> Int
VarName -> [VarName]
VarName -> VarName
VarName -> VarName -> [VarName]
VarName -> VarName -> VarName -> [VarName]
(VarName -> VarName)
-> (VarName -> VarName)
-> (Int -> VarName)
-> (VarName -> Int)
-> (VarName -> [VarName])
-> (VarName -> VarName -> [VarName])
-> (VarName -> VarName -> [VarName])
-> (VarName -> VarName -> VarName -> [VarName])
-> Enum VarName
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: VarName -> VarName -> VarName -> [VarName]
$cenumFromThenTo :: VarName -> VarName -> VarName -> [VarName]
enumFromTo :: VarName -> VarName -> [VarName]
$cenumFromTo :: VarName -> VarName -> [VarName]
enumFromThen :: VarName -> VarName -> [VarName]
$cenumFromThen :: VarName -> VarName -> [VarName]
enumFrom :: VarName -> [VarName]
$cenumFrom :: VarName -> [VarName]
fromEnum :: VarName -> Int
$cfromEnum :: VarName -> Int
toEnum :: Int -> VarName
$ctoEnum :: Int -> VarName
pred :: VarName -> VarName
$cpred :: VarName -> VarName
succ :: VarName -> VarName
$csucc :: VarName -> VarName
Enum, VarName
VarName -> VarName -> Bounded VarName
forall a. a -> a -> Bounded a
maxBound :: VarName
$cmaxBound :: VarName
minBound :: VarName
$cminBound :: VarName
Bounded)

data Error = Missing VarName | Invalid VarName | WrongProcess | NoSuchName Name
    deriving stock Int -> Error -> ShowS
[Error] -> ShowS
Error -> String
(Int -> Error -> ShowS)
-> (Error -> String) -> ([Error] -> ShowS) -> Show Error
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Error] -> ShowS
$cshowList :: [Error] -> ShowS
show :: Error -> String
$cshow :: Error -> String
showsPrec :: Int -> Error -> ShowS
$cshowsPrec :: Int -> Error -> ShowS
Show
    deriving anyclass Show Error
Typeable Error
Typeable Error
-> Show Error
-> (Error -> SomeException)
-> (SomeException -> Maybe Error)
-> (Error -> String)
-> Exception Error
SomeException -> Maybe Error
Error -> String
Error -> SomeException
forall e.
Typeable e
-> Show e
-> (e -> SomeException)
-> (SomeException -> Maybe e)
-> (e -> String)
-> Exception e
displayException :: Error -> String
$cdisplayException :: Error -> String
fromException :: SomeException -> Maybe Error
$cfromException :: SomeException -> Maybe Error
toException :: Error -> SomeException
$ctoException :: Error -> SomeException
$cp2Exception :: Show Error
$cp1Exception :: Typeable Error
Exception