{-# LANGUAGE DataKinds #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE ScopedTypeVariables #-}
module System.Nix.Store.Remote.Types
  ( MonadStore
  , StoreConfig(..)
  , Logger(..)
  , Field(..)
  , getStoreDir
  , getLog
  , flushLog
  , gotError
  , getError
  , setData
  , clearData
  )
where


import           Data.ByteString                ( ByteString )
import qualified Data.ByteString.Lazy          as BSL
import           Network.Socket                 ( Socket )
import           Control.Monad.Except
import           Control.Monad.Reader
import           Control.Monad.State

data StoreConfig = StoreConfig
  { StoreConfig -> FilePath
storeDir    :: FilePath
  , StoreConfig -> Socket
storeSocket :: Socket
  }

type MonadStore a
  = ExceptT
      String
      (StateT (Maybe BSL.ByteString, [Logger]) (ReaderT StoreConfig IO))
      a

type ActivityID = Int
type ActivityParentID = Int
type ActivityType = Int
type Verbosity = Int
type ResultType = Int

data Field = LogStr ByteString | LogInt Int
  deriving (Field -> Field -> Bool
(Field -> Field -> Bool) -> (Field -> Field -> Bool) -> Eq Field
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Field -> Field -> Bool
$c/= :: Field -> Field -> Bool
== :: Field -> Field -> Bool
$c== :: Field -> Field -> Bool
Eq, Eq Field
Eq Field
-> (Field -> Field -> Ordering)
-> (Field -> Field -> Bool)
-> (Field -> Field -> Bool)
-> (Field -> Field -> Bool)
-> (Field -> Field -> Bool)
-> (Field -> Field -> Field)
-> (Field -> Field -> Field)
-> Ord Field
Field -> Field -> Bool
Field -> Field -> Ordering
Field -> Field -> Field
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 :: Field -> Field -> Field
$cmin :: Field -> Field -> Field
max :: Field -> Field -> Field
$cmax :: Field -> Field -> Field
>= :: Field -> Field -> Bool
$c>= :: Field -> Field -> Bool
> :: Field -> Field -> Bool
$c> :: Field -> Field -> Bool
<= :: Field -> Field -> Bool
$c<= :: Field -> Field -> Bool
< :: Field -> Field -> Bool
$c< :: Field -> Field -> Bool
compare :: Field -> Field -> Ordering
$ccompare :: Field -> Field -> Ordering
$cp1Ord :: Eq Field
Ord, Int -> Field -> ShowS
[Field] -> ShowS
Field -> FilePath
(Int -> Field -> ShowS)
-> (Field -> FilePath) -> ([Field] -> ShowS) -> Show Field
forall a.
(Int -> a -> ShowS) -> (a -> FilePath) -> ([a] -> ShowS) -> Show a
showList :: [Field] -> ShowS
$cshowList :: [Field] -> ShowS
show :: Field -> FilePath
$cshow :: Field -> FilePath
showsPrec :: Int -> Field -> ShowS
$cshowsPrec :: Int -> Field -> ShowS
Show)

data Logger =
    Next          ByteString
  | Read          Int            -- data needed from source
  | Write         ByteString -- data for sink
  | Last
  | Error         Int ByteString
  | StartActivity ActivityID Verbosity ActivityType ByteString [Field] ActivityParentID
  | StopActivity  ActivityID
  | Result        ActivityID ResultType [Field]
  deriving (Logger -> Logger -> Bool
(Logger -> Logger -> Bool)
-> (Logger -> Logger -> Bool) -> Eq Logger
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Logger -> Logger -> Bool
$c/= :: Logger -> Logger -> Bool
== :: Logger -> Logger -> Bool
$c== :: Logger -> Logger -> Bool
Eq, Eq Logger
Eq Logger
-> (Logger -> Logger -> Ordering)
-> (Logger -> Logger -> Bool)
-> (Logger -> Logger -> Bool)
-> (Logger -> Logger -> Bool)
-> (Logger -> Logger -> Bool)
-> (Logger -> Logger -> Logger)
-> (Logger -> Logger -> Logger)
-> Ord Logger
Logger -> Logger -> Bool
Logger -> Logger -> Ordering
Logger -> Logger -> Logger
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 :: Logger -> Logger -> Logger
$cmin :: Logger -> Logger -> Logger
max :: Logger -> Logger -> Logger
$cmax :: Logger -> Logger -> Logger
>= :: Logger -> Logger -> Bool
$c>= :: Logger -> Logger -> Bool
> :: Logger -> Logger -> Bool
$c> :: Logger -> Logger -> Bool
<= :: Logger -> Logger -> Bool
$c<= :: Logger -> Logger -> Bool
< :: Logger -> Logger -> Bool
$c< :: Logger -> Logger -> Bool
compare :: Logger -> Logger -> Ordering
$ccompare :: Logger -> Logger -> Ordering
$cp1Ord :: Eq Logger
Ord, Int -> Logger -> ShowS
[Logger] -> ShowS
Logger -> FilePath
(Int -> Logger -> ShowS)
-> (Logger -> FilePath) -> ([Logger] -> ShowS) -> Show Logger
forall a.
(Int -> a -> ShowS) -> (a -> FilePath) -> ([a] -> ShowS) -> Show a
showList :: [Logger] -> ShowS
$cshowList :: [Logger] -> ShowS
show :: Logger -> FilePath
$cshow :: Logger -> FilePath
showsPrec :: Int -> Logger -> ShowS
$cshowsPrec :: Int -> Logger -> ShowS
Show)

isError :: Logger -> Bool
isError :: Logger -> Bool
isError (Error Int
_ ByteString
_) = Bool
True
isError Logger
_           = Bool
False

gotError :: MonadStore Bool
gotError :: MonadStore Bool
gotError = (Logger -> Bool) -> [Logger] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any Logger -> Bool
isError ([Logger] -> Bool)
-> ((Maybe ByteString, [Logger]) -> [Logger])
-> (Maybe ByteString, [Logger])
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Maybe ByteString, [Logger]) -> [Logger]
forall a b. (a, b) -> b
snd ((Maybe ByteString, [Logger]) -> Bool)
-> ExceptT
     FilePath
     (StateT (Maybe ByteString, [Logger]) (ReaderT StoreConfig IO))
     (Maybe ByteString, [Logger])
-> MonadStore Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ExceptT
  FilePath
  (StateT (Maybe ByteString, [Logger]) (ReaderT StoreConfig IO))
  (Maybe ByteString, [Logger])
forall s (m :: * -> *). MonadState s m => m s
get

getError :: MonadStore [Logger]
getError :: MonadStore [Logger]
getError = (Logger -> Bool) -> [Logger] -> [Logger]
forall a. (a -> Bool) -> [a] -> [a]
filter Logger -> Bool
isError ([Logger] -> [Logger])
-> ((Maybe ByteString, [Logger]) -> [Logger])
-> (Maybe ByteString, [Logger])
-> [Logger]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Maybe ByteString, [Logger]) -> [Logger]
forall a b. (a, b) -> b
snd ((Maybe ByteString, [Logger]) -> [Logger])
-> ExceptT
     FilePath
     (StateT (Maybe ByteString, [Logger]) (ReaderT StoreConfig IO))
     (Maybe ByteString, [Logger])
-> MonadStore [Logger]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ExceptT
  FilePath
  (StateT (Maybe ByteString, [Logger]) (ReaderT StoreConfig IO))
  (Maybe ByteString, [Logger])
forall s (m :: * -> *). MonadState s m => m s
get

getLog :: MonadStore [Logger]
getLog :: MonadStore [Logger]
getLog = (Maybe ByteString, [Logger]) -> [Logger]
forall a b. (a, b) -> b
snd ((Maybe ByteString, [Logger]) -> [Logger])
-> ExceptT
     FilePath
     (StateT (Maybe ByteString, [Logger]) (ReaderT StoreConfig IO))
     (Maybe ByteString, [Logger])
-> MonadStore [Logger]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ExceptT
  FilePath
  (StateT (Maybe ByteString, [Logger]) (ReaderT StoreConfig IO))
  (Maybe ByteString, [Logger])
forall s (m :: * -> *). MonadState s m => m s
get

flushLog :: MonadStore ()
flushLog :: MonadStore ()
flushLog = ((Maybe ByteString, [Logger]) -> (Maybe ByteString, [Logger]))
-> MonadStore ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify (\(Maybe ByteString
a, [Logger]
_b) -> (Maybe ByteString
a, []))

setData :: BSL.ByteString -> MonadStore ()
setData :: ByteString -> MonadStore ()
setData ByteString
x = ((Maybe ByteString, [Logger]) -> (Maybe ByteString, [Logger]))
-> MonadStore ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify (\(Maybe ByteString
_, [Logger]
b) -> (ByteString -> Maybe ByteString
forall a. a -> Maybe a
Just ByteString
x, [Logger]
b))

clearData :: MonadStore ()
clearData :: MonadStore ()
clearData = ((Maybe ByteString, [Logger]) -> (Maybe ByteString, [Logger]))
-> MonadStore ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify (\(Maybe ByteString
_, [Logger]
b) -> (Maybe ByteString
forall a. Maybe a
Nothing, [Logger]
b))

getStoreDir :: MonadStore FilePath
getStoreDir :: MonadStore FilePath
getStoreDir = StoreConfig -> FilePath
storeDir (StoreConfig -> FilePath)
-> ExceptT
     FilePath
     (StateT (Maybe ByteString, [Logger]) (ReaderT StoreConfig IO))
     StoreConfig
-> MonadStore FilePath
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ExceptT
  FilePath
  (StateT (Maybe ByteString, [Logger]) (ReaderT StoreConfig IO))
  StoreConfig
forall r (m :: * -> *). MonadReader r m => m r
ask