{-# LANGUAGE DeriveGeneric #-}

-- | Functions related to obtaining information about the 'db-analyser' run.
--
-- Metadata includes information such as:
--
-- - RTS flags.
-- - Compiler version.
-- - OS and architecture.
--
-- See 'Metadata' and 'getMetadata' for more details.
module Cardano.Tools.DBAnalyser.Analysis.BenchmarkLedgerOps.Metadata
  ( Metadata (..)
  , getMetadata
  ) where

import Cardano.Tools.DBAnalyser.Types (LedgerApplicationMode (..))
import Cardano.Tools.GitRev (gitRev)
import Data.Aeson (ToJSON)
import qualified Data.Aeson as Aeson
import qualified Data.Text as T
import qualified Data.Version
import Data.Word (Word32, Word64)
import GHC.Generics (Generic)
import qualified GHC.RTS.Flags as RTS
import qualified System.Info

data Metadata = Metadata
  { Metadata -> Word32
rtsGCMaxStkSize :: Word32
  , Metadata -> Word32
rtsGCMaxHeapSize :: Word32
  , Metadata -> Word64
rtsConcurrentCtxtSwitchTime :: Word64
  , Metadata -> Word32
rtsParNCapabilities :: Word32
  , Metadata -> String
compilerVersion :: String
  , Metadata -> String
compilerName :: String
  , Metadata -> String
operatingSystem :: String
  , Metadata -> String
machineArchitecture :: String
  , Metadata -> String
gitRevison :: String
  , Metadata -> String
ledgerApplicationMode :: String
  }
  deriving ((forall x. Metadata -> Rep Metadata x)
-> (forall x. Rep Metadata x -> Metadata) -> Generic Metadata
forall x. Rep Metadata x -> Metadata
forall x. Metadata -> Rep Metadata x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Metadata -> Rep Metadata x
from :: forall x. Metadata -> Rep Metadata x
$cto :: forall x. Rep Metadata x -> Metadata
to :: forall x. Rep Metadata x -> Metadata
Generic, Int -> Metadata -> ShowS
[Metadata] -> ShowS
Metadata -> String
(Int -> Metadata -> ShowS)
-> (Metadata -> String) -> ([Metadata] -> ShowS) -> Show Metadata
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Metadata -> ShowS
showsPrec :: Int -> Metadata -> ShowS
$cshow :: Metadata -> String
show :: Metadata -> String
$cshowList :: [Metadata] -> ShowS
showList :: [Metadata] -> ShowS
Show, Metadata -> Metadata -> Bool
(Metadata -> Metadata -> Bool)
-> (Metadata -> Metadata -> Bool) -> Eq Metadata
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Metadata -> Metadata -> Bool
== :: Metadata -> Metadata -> Bool
$c/= :: Metadata -> Metadata -> Bool
/= :: Metadata -> Metadata -> Bool
Eq)

instance ToJSON Metadata where
  toEncoding :: Metadata -> Encoding
toEncoding = Options -> Metadata -> Encoding
forall a.
(Generic a, GToJSON' Encoding Zero (Rep a)) =>
Options -> a -> Encoding
Aeson.genericToEncoding Options
Aeson.defaultOptions

getMetadata :: LedgerApplicationMode -> IO Metadata
getMetadata :: LedgerApplicationMode -> IO Metadata
getMetadata LedgerApplicationMode
lgrAppMode = do
  rtsFlags <- IO RTSFlags
RTS.getRTSFlags
  pure $
    Metadata
      { rtsGCMaxStkSize = RTS.maxStkSize $ RTS.gcFlags rtsFlags
      , rtsGCMaxHeapSize = RTS.maxHeapSize $ RTS.gcFlags rtsFlags
      , rtsConcurrentCtxtSwitchTime = RTS.ctxtSwitchTime $ RTS.concurrentFlags rtsFlags
      , rtsParNCapabilities = RTS.nCapabilities $ RTS.parFlags rtsFlags
      , compilerVersion = Data.Version.showVersion System.Info.compilerVersion
      , compilerName = System.Info.compilerName
      , operatingSystem = System.Info.os
      , machineArchitecture = System.Info.arch
      , gitRevison = T.unpack gitRev
      , ledgerApplicationMode = case lgrAppMode of
          LedgerApplicationMode
LedgerApply -> String
"full-application"
          LedgerApplicationMode
LedgerReapply -> String
"reapplication"
      }