module HaskellWorks.CabalCache.IO.Console
  ( putStrLn
  , print
  , hPutStrLn
  , hPrint
  ) where

import Control.Exception      (bracket_)
import Control.Monad.IO.Class (MonadIO, liftIO)
import Data.Text              (Text)
import Prelude                (IO, Show (..), ($), (.))

import qualified Control.Concurrent.QSem as IO
import qualified Data.Text.IO            as T
import qualified System.IO               as IO
import qualified System.IO.Unsafe        as IO

sem :: IO.QSem
sem :: QSem
sem = IO QSem -> QSem
forall a. IO a -> a
IO.unsafePerformIO (IO QSem -> QSem) -> IO QSem -> QSem
forall a b. (a -> b) -> a -> b
$ Int -> IO QSem
IO.newQSem Int
1
{-# NOINLINE sem #-}

consoleBracket :: IO a -> IO a
consoleBracket :: IO a -> IO a
consoleBracket = IO () -> IO () -> IO a -> IO a
forall a b c. IO a -> IO b -> IO c -> IO c
bracket_ (QSem -> IO ()
IO.waitQSem QSem
sem) (QSem -> IO ()
IO.signalQSem QSem
sem)

putStrLn :: MonadIO m => Text -> m ()
putStrLn :: Text -> m ()
putStrLn = IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> (Text -> IO ()) -> Text -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IO () -> IO ()
forall a. IO a -> IO a
consoleBracket (IO () -> IO ()) -> (Text -> IO ()) -> Text -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> IO ()
T.putStrLn

print :: (MonadIO m, Show a) => a -> m ()
print :: a -> m ()
print = IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> (a -> IO ()) -> a -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IO () -> IO ()
forall a. IO a -> IO a
consoleBracket (IO () -> IO ()) -> (a -> IO ()) -> a -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> IO ()
forall a. Show a => a -> IO ()
IO.print

hPutStrLn :: MonadIO m => IO.Handle -> Text -> m ()
hPutStrLn :: Handle -> Text -> m ()
hPutStrLn Handle
h = IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> (Text -> IO ()) -> Text -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IO () -> IO ()
forall a. IO a -> IO a
consoleBracket (IO () -> IO ()) -> (Text -> IO ()) -> Text -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> Text -> IO ()
T.hPutStrLn Handle
h

hPrint :: (MonadIO m, Show a) => IO.Handle -> a -> m ()
hPrint :: Handle -> a -> m ()
hPrint Handle
h = IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> (a -> IO ()) -> a -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IO () -> IO ()
forall a. IO a -> IO a
consoleBracket (IO () -> IO ()) -> (a -> IO ()) -> a -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> a -> IO ()
forall a. Show a => Handle -> a -> IO ()
IO.hPrint Handle
h