module Ouroboros.Consensus.Util.MonadSTM.NormalForm
  ( module LazySTM
  , module Ouroboros.Consensus.Util.MonadSTM.StrictSVar
  , module StrictSTM
  , newEmptySVar
  , newSVar

    -- * Temporary
  , uncheckedNewEmptySVar
  , uncheckedNewSVar
  ) where

import Control.Concurrent.Class.MonadSTM.Strict.TMVar as StrictSTM hiding
  ( newTMVar
  , newTMVarIO
  , traceTMVar
  , traceTMVarIO
  )
import Control.Concurrent.Class.MonadSTM.TBQueue as LazySTM
import Control.Concurrent.Class.MonadSTM.TQueue as LazySTM
import Control.Monad.Class.MonadSTM as StrictSTM hiding
  ( traceTVar
  , traceTVarIO
  )
import GHC.Stack
import NoThunks.Class (NoThunks (..), unsafeNoThunks)
import Ouroboros.Consensus.Util.MonadSTM.StrictSVar hiding
  ( newEmptySVar
  , newEmptySVarWithInvariant
  , newSVar
  , newSVarWithInvariant
  )
import qualified Ouroboros.Consensus.Util.MonadSTM.StrictSVar as Strict

-- TODO: use strict versions of 'TQueue' and 'TBQueue'.  Previously the
-- 'Control.Monad.Class.MonadSTM.Strict' was imported which
-- exported lazy 'TQueue' and 'TBQueue',  I (@coot) think that the intention was
-- to use strict versions.

{-------------------------------------------------------------------------------
  Wrappers that check for thunks
-------------------------------------------------------------------------------}

newSVar ::
  (MonadSTM m, HasCallStack, NoThunks a) =>
  a -> m (StrictSVar m a)
newSVar :: forall (m :: * -> *) a.
(MonadSTM m, HasCallStack, NoThunks a) =>
a -> m (StrictSVar m a)
newSVar = (a -> Maybe String) -> a -> m (StrictSVar m a)
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
(a -> Maybe String) -> a -> m (StrictSVar m a)
Strict.newSVarWithInvariant ((ThunkInfo -> String) -> Maybe ThunkInfo -> Maybe String
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ThunkInfo -> String
forall a. Show a => a -> String
show (Maybe ThunkInfo -> Maybe String)
-> (a -> Maybe ThunkInfo) -> a -> Maybe String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Maybe ThunkInfo
forall a. NoThunks a => a -> Maybe ThunkInfo
unsafeNoThunks)

newEmptySVar :: (MonadSTM m, NoThunks a) => a -> m (StrictSVar m a)
newEmptySVar :: forall (m :: * -> *) a.
(MonadSTM m, NoThunks a) =>
a -> m (StrictSVar m a)
newEmptySVar = (a -> Maybe String) -> a -> m (StrictSVar m a)
forall (m :: * -> *) a.
MonadSTM m =>
(a -> Maybe String) -> a -> m (StrictSVar m a)
Strict.newEmptySVarWithInvariant ((ThunkInfo -> String) -> Maybe ThunkInfo -> Maybe String
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ThunkInfo -> String
forall a. Show a => a -> String
show (Maybe ThunkInfo -> Maybe String)
-> (a -> Maybe ThunkInfo) -> a -> Maybe String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Maybe ThunkInfo
forall a. NoThunks a => a -> Maybe ThunkInfo
unsafeNoThunks)

{-------------------------------------------------------------------------------
  Unchecked wrappers (where we don't check for thunks)

  These will eventually be removed.
-------------------------------------------------------------------------------}

uncheckedNewSVar :: MonadSTM m => a -> m (StrictSVar m a)
uncheckedNewSVar :: forall (m :: * -> *) a. MonadSTM m => a -> m (StrictSVar m a)
uncheckedNewSVar = a -> m (StrictSVar m a)
forall (m :: * -> *) a. MonadSTM m => a -> m (StrictSVar m a)
Strict.newSVar

uncheckedNewEmptySVar :: MonadSTM m => a -> m (StrictSVar m a)
uncheckedNewEmptySVar :: forall (m :: * -> *) a. MonadSTM m => a -> m (StrictSVar m a)
uncheckedNewEmptySVar = a -> m (StrictSVar m a)
forall (m :: * -> *) a. MonadSTM m => a -> m (StrictSVar m a)
Strict.newEmptySVar