{-# OPTIONS_GHC -Wno-redundant-constraints #-}

-- | Provides a static effect for "System.Posix.Signals".
--
-- @since 0.1
module Effectful.Posix.Signals.Static
  ( -- * Effect
    PosixSignals,
    raiseSignal,
    signalProcess,
    signalProcessGroup,
    installHandler,
    getSignalMask,
    setSignalMask,
    blockSignals,
    unblockSignals,
    scheduleAlarm,
    getPendingSignals,
    awaitSignal,
    setStoppedChildFlag,
    queryStoppedChildFlag,

    -- ** Handler
    runPosixSignals,

    -- * Posix Handler
    Handler (..),
    Handler.mapHandler,
    Handler.handlerToPosix,
    Handler.handlerFromPosix,

    -- * Re-exports
    Signal,
    SignalSet,
    ProcessID,
    ProcessGroupID,
  )
where

import Effectful
  ( Dispatch (Static),
    DispatchOf,
    Eff,
    Effect,
    IOE,
    type (:>),
  )
import Effectful.Dispatch.Static
  ( HasCallStack,
    SideEffects (WithSideEffects),
    StaticRep,
    evalStaticRep,
    seqUnliftIO,
    unsafeEff,
    unsafeEff_,
  )
import Effectful.Posix.Signals.Handler (Handler)
import Effectful.Posix.Signals.Handler qualified as Handler
import System.Posix.Signals (Signal, SignalSet)
import System.Posix.Signals qualified as Signals
import System.Posix.Types (ProcessGroupID, ProcessID)

-- | Provides a static effect for "System.Posix.Signals".
--
-- @since 0.1
data PosixSignals :: Effect

type instance DispatchOf PosixSignals = Static WithSideEffects

data instance StaticRep PosixSignals = MkPosixSignals

-- | Runs a PosixSignals effect.
--
-- @since 0.1
runPosixSignals ::
  (HasCallStack, IOE :> es) =>
  Eff (PosixSignals : es) a ->
  Eff es a
runPosixSignals :: forall (es :: [Effect]) a.
(HasCallStack, IOE :> es) =>
Eff (PosixSignals : es) a -> Eff es a
runPosixSignals = StaticRep PosixSignals -> Eff (PosixSignals : es) a -> Eff es a
forall (e :: Effect) (sideEffects :: SideEffects) (es :: [Effect])
       a.
(HasCallStack, DispatchOf e ~ 'Static sideEffects,
 MaybeIOE sideEffects es) =>
StaticRep e -> Eff (e : es) a -> Eff es a
evalStaticRep StaticRep PosixSignals
MkPosixSignals

-- | Lifted 'Signals.raiseSignal'.
--
-- @since 0.1
raiseSignal ::
  ( HasCallStack,
    PosixSignals :> es
  ) =>
  Signal ->
  Eff es ()
raiseSignal :: forall (es :: [Effect]).
(HasCallStack, PosixSignals :> es) =>
Signal -> Eff es ()
raiseSignal = IO () -> Eff es ()
forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ (IO () -> Eff es ()) -> (Signal -> IO ()) -> Signal -> Eff es ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Signal -> IO ()
Signals.raiseSignal

-- | Lifted 'Signals.signalProcess'.
--
-- @since 0.1
signalProcess ::
  ( HasCallStack,
    PosixSignals :> es
  ) =>
  Signal ->
  ProcessID ->
  Eff es ()
signalProcess :: forall (es :: [Effect]).
(HasCallStack, PosixSignals :> es) =>
Signal -> ProcessID -> Eff es ()
signalProcess Signal
x1 = IO () -> Eff es ()
forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ (IO () -> Eff es ())
-> (ProcessID -> IO ()) -> ProcessID -> Eff es ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Signal -> ProcessID -> IO ()
Signals.signalProcess Signal
x1

-- | Lifted 'Signals.signalProcessGroup'.
--
-- @since 0.1
signalProcessGroup ::
  ( HasCallStack,
    PosixSignals :> es
  ) =>
  Signal ->
  ProcessGroupID ->
  Eff es ()
signalProcessGroup :: forall (es :: [Effect]).
(HasCallStack, PosixSignals :> es) =>
Signal -> ProcessID -> Eff es ()
signalProcessGroup Signal
x1 = IO () -> Eff es ()
forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ (IO () -> Eff es ())
-> (ProcessID -> IO ()) -> ProcessID -> Eff es ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Signal -> ProcessID -> IO ()
Signals.signalProcessGroup Signal
x1

-- | Lifted 'Signals.installHandler'.
--
-- @since 0.1
installHandler ::
  ( HasCallStack,
    PosixSignals :> es
  ) =>
  Signal ->
  Handler (Eff es) ->
  Maybe SignalSet ->
  Eff es (Handler (Eff es))
installHandler :: forall (es :: [Effect]).
(HasCallStack, PosixSignals :> es) =>
Signal
-> Handler (Eff es) -> Maybe SignalSet -> Eff es (Handler (Eff es))
installHandler Signal
s Handler (Eff es)
h Maybe SignalSet
ms =
  (Env es -> IO (Handler (Eff es))) -> Eff es (Handler (Eff es))
forall (es :: [Effect]) a. (Env es -> IO a) -> Eff es a
unsafeEff ((Env es -> IO (Handler (Eff es))) -> Eff es (Handler (Eff es)))
-> (Env es -> IO (Handler (Eff es))) -> Eff es (Handler (Eff es))
forall a b. (a -> b) -> a -> b
$ \Env es
env -> Env es
-> ((forall r. Eff es r -> IO r) -> IO (Handler (Eff es)))
-> IO (Handler (Eff es))
forall (es :: [Effect]) a.
HasCallStack =>
Env es -> ((forall r. Eff es r -> IO r) -> IO a) -> IO a
seqUnliftIO Env es
env (((forall r. Eff es r -> IO r) -> IO (Handler (Eff es)))
 -> IO (Handler (Eff es)))
-> ((forall r. Eff es r -> IO r) -> IO (Handler (Eff es)))
-> IO (Handler (Eff es))
forall a b. (a -> b) -> a -> b
$ \forall r. Eff es r -> IO r
runInIO ->
    (Handler -> Handler (Eff es))
-> IO Handler -> IO (Handler (Eff es))
forall a b. (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((forall x. IO x -> Eff es x) -> Handler IO -> Handler (Eff es)
forall (m :: * -> *) (n :: * -> *).
(forall x. m x -> n x) -> Handler m -> Handler n
Handler.mapHandler IO x -> Eff es x
forall x. IO x -> Eff es x
forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ (Handler IO -> Handler (Eff es))
-> (Handler -> Handler IO) -> Handler -> Handler (Eff es)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handler -> Handler IO
Handler.handlerFromPosix)
      (IO Handler -> IO (Handler (Eff es)))
-> (Handler (Eff es) -> IO Handler)
-> Handler (Eff es)
-> IO (Handler (Eff es))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (\Handler
x -> Signal -> Handler -> Maybe SignalSet -> IO Handler
Signals.installHandler Signal
s Handler
x Maybe SignalSet
ms)
      (Handler -> IO Handler)
-> (Handler (Eff es) -> Handler) -> Handler (Eff es) -> IO Handler
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handler IO -> Handler
Handler.handlerToPosix
      (Handler IO -> Handler)
-> (Handler (Eff es) -> Handler IO) -> Handler (Eff es) -> Handler
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (forall r. Eff es r -> IO r) -> Handler (Eff es) -> Handler IO
forall (m :: * -> *) (n :: * -> *).
(forall x. m x -> n x) -> Handler m -> Handler n
Handler.mapHandler Eff es x -> IO x
forall r. Eff es r -> IO r
runInIO
      (Handler (Eff es) -> IO (Handler (Eff es)))
-> Handler (Eff es) -> IO (Handler (Eff es))
forall a b. (a -> b) -> a -> b
$ Handler (Eff es)
h

-- | Lifted 'Signals.getSignalMask'.
--
-- @since 0.1
getSignalMask ::
  ( HasCallStack,
    PosixSignals :> es
  ) =>
  Eff es SignalSet
getSignalMask :: forall (es :: [Effect]).
(HasCallStack, PosixSignals :> es) =>
Eff es SignalSet
getSignalMask = IO SignalSet -> Eff es SignalSet
forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ IO SignalSet
Signals.getSignalMask

-- | Lifted 'Signals.setSignalMask'.
--
-- @since 0.1
setSignalMask ::
  ( HasCallStack,
    PosixSignals :> es
  ) =>
  SignalSet ->
  Eff es ()
setSignalMask :: forall (es :: [Effect]).
(HasCallStack, PosixSignals :> es) =>
SignalSet -> Eff es ()
setSignalMask = IO () -> Eff es ()
forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ (IO () -> Eff es ())
-> (SignalSet -> IO ()) -> SignalSet -> Eff es ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SignalSet -> IO ()
Signals.setSignalMask

-- | Lifted 'Signals.blockSignals'.
--
-- @since 0.1
blockSignals ::
  ( HasCallStack,
    PosixSignals :> es
  ) =>
  SignalSet ->
  Eff es ()
blockSignals :: forall (es :: [Effect]).
(HasCallStack, PosixSignals :> es) =>
SignalSet -> Eff es ()
blockSignals = IO () -> Eff es ()
forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ (IO () -> Eff es ())
-> (SignalSet -> IO ()) -> SignalSet -> Eff es ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SignalSet -> IO ()
Signals.blockSignals

-- | Lifted 'Signals.unblockSignals'.
--
-- @since 0.1
unblockSignals ::
  ( HasCallStack,
    PosixSignals :> es
  ) =>
  SignalSet ->
  Eff es ()
unblockSignals :: forall (es :: [Effect]).
(HasCallStack, PosixSignals :> es) =>
SignalSet -> Eff es ()
unblockSignals = IO () -> Eff es ()
forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ (IO () -> Eff es ())
-> (SignalSet -> IO ()) -> SignalSet -> Eff es ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SignalSet -> IO ()
Signals.unblockSignals

-- | Lifted 'Signals.scheduleAlarm'.
--
-- @since 0.1
scheduleAlarm ::
  ( HasCallStack,
    PosixSignals :> es
  ) =>
  Int ->
  Eff es Int
scheduleAlarm :: forall (es :: [Effect]).
(HasCallStack, PosixSignals :> es) =>
Int -> Eff es Int
scheduleAlarm = IO Int -> Eff es Int
forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ (IO Int -> Eff es Int) -> (Int -> IO Int) -> Int -> Eff es Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> IO Int
Signals.scheduleAlarm

-- | Lifted 'Signals.getPendingSignals'.
--
-- @since 0.1
getPendingSignals ::
  ( HasCallStack,
    PosixSignals :> es
  ) =>
  Eff es SignalSet
getPendingSignals :: forall (es :: [Effect]).
(HasCallStack, PosixSignals :> es) =>
Eff es SignalSet
getPendingSignals = IO SignalSet -> Eff es SignalSet
forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ IO SignalSet
Signals.getPendingSignals

-- | Lifted 'Signals.awaitSignal'.
--
-- @since 0.1
awaitSignal ::
  ( HasCallStack,
    PosixSignals :> es
  ) =>
  Maybe SignalSet ->
  Eff es ()
awaitSignal :: forall (es :: [Effect]).
(HasCallStack, PosixSignals :> es) =>
Maybe SignalSet -> Eff es ()
awaitSignal = IO () -> Eff es ()
forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ (IO () -> Eff es ())
-> (Maybe SignalSet -> IO ()) -> Maybe SignalSet -> Eff es ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe SignalSet -> IO ()
Signals.awaitSignal

-- | Lifted 'Signals.setStoppedChildFlag'.
--
-- @since 0.1
setStoppedChildFlag ::
  ( HasCallStack,
    PosixSignals :> es
  ) =>
  Bool ->
  Eff es Bool
setStoppedChildFlag :: forall (es :: [Effect]).
(HasCallStack, PosixSignals :> es) =>
Bool -> Eff es Bool
setStoppedChildFlag = IO Bool -> Eff es Bool
forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ (IO Bool -> Eff es Bool)
-> (Bool -> IO Bool) -> Bool -> Eff es Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> IO Bool
Signals.setStoppedChildFlag

-- | Lifted 'Signals.queryStoppedChildFlag'.
--
-- @since 0.1
queryStoppedChildFlag ::
  ( HasCallStack,
    PosixSignals :> es
  ) =>
  Eff es Bool
queryStoppedChildFlag :: forall (es :: [Effect]).
(HasCallStack, PosixSignals :> es) =>
Eff es Bool
queryStoppedChildFlag = IO Bool -> Eff es Bool
forall a (es :: [Effect]). IO a -> Eff es a
unsafeEff_ IO Bool
Signals.queryStoppedChildFlag