module Test.Sandwich.Formatters.TerminalUI.Draw.RunTimes (getRunTimes) where

import Brick
import Data.Maybe
import Data.String.Interpolate
import Data.Time.Clock
import qualified Graphics.Vty as V
import Lens.Micro
import Test.Sandwich.Formatters.Common.Util
import Test.Sandwich.Formatters.TerminalUI.AttrMap
import Test.Sandwich.Formatters.TerminalUI.Types


Int
minGray :: Int = Int
50
Int
maxGray :: Int = Int
255

getRunTimes :: AppState
-> UTCTime
-> UTCTime
-> Maybe NominalDiffTime
-> Maybe NominalDiffTime
-> Bool
-> Widget n
getRunTimes AppState
app UTCTime
startTime UTCTime
endTime Maybe NominalDiffTime
statusSetupTime Maybe NominalDiffTime
statusTeardownTime Bool
showEllipses = forall n. Image -> Widget n
raw Image
setupWork forall n. Widget n -> Widget n -> Widget n
<+> forall n. Image -> Widget n
raw Image
actualWork forall n. Widget n -> Widget n -> Widget n
<+> forall n. Image -> Widget n
raw Image
teardownWork
  where
    totalElapsed :: NominalDiffTime
totalElapsed = UTCTime -> UTCTime -> NominalDiffTime
diffUTCTime (AppState
app forall s a. s -> Getting a s a -> a
^. Lens' AppState UTCTime
appCurrentTime) (AppState
app forall s a. s -> Getting a s a -> a
^. Lens' AppState UTCTime
appStartTime)

    actualWorkTime :: NominalDiffTime
actualWorkTime = (UTCTime -> UTCTime -> NominalDiffTime
diffUTCTime UTCTime
endTime UTCTime
startTime) forall a. Num a => a -> a -> a
- (forall a. a -> Maybe a -> a
fromMaybe NominalDiffTime
0 Maybe NominalDiffTime
statusSetupTime) forall a. Num a => a -> a -> a
- (forall a. a -> Maybe a -> a
fromMaybe NominalDiffTime
0 Maybe NominalDiffTime
statusTeardownTime)

    setupWork :: Image
setupWork = forall b a. b -> (a -> b) -> Maybe a -> b
maybe forall a. Monoid a => a
mempty (\NominalDiffTime
dt -> Attr -> String -> Image
V.string (NominalDiffTime -> NominalDiffTime -> Attr
getAttr NominalDiffTime
totalElapsed NominalDiffTime
dt) [i|(#{formatNominalDiffTime dt}) + |]) Maybe NominalDiffTime
statusSetupTime
    actualWork :: Image
actualWork = Attr -> String -> Image
V.string (NominalDiffTime -> NominalDiffTime -> Attr
getAttr NominalDiffTime
totalElapsed NominalDiffTime
actualWorkTime) (NominalDiffTime -> String
formatNominalDiffTime NominalDiffTime
actualWorkTime forall a. Semigroup a => a -> a -> a
<> (if Bool
showEllipses then String
"..." else String
""))
    teardownWork :: Image
teardownWork = forall b a. b -> (a -> b) -> Maybe a -> b
maybe forall a. Monoid a => a
mempty (\NominalDiffTime
dt -> Attr -> String -> Image
V.string (NominalDiffTime -> NominalDiffTime -> Attr
getAttr NominalDiffTime
totalElapsed NominalDiffTime
dt) [i| + (#{formatNominalDiffTime dt})|]) Maybe NominalDiffTime
statusTeardownTime

getAttr :: NominalDiffTime -> NominalDiffTime -> V.Attr
getAttr :: NominalDiffTime -> NominalDiffTime -> Attr
getAttr NominalDiffTime
totalElapsed NominalDiffTime
dt = V.Attr {
  attrStyle :: MaybeDefault Style
V.attrStyle = forall v. MaybeDefault v
V.Default
  , attrForeColor :: MaybeDefault Color
V.attrForeColor = forall v. v -> MaybeDefault v
V.SetTo forall a b. (a -> b) -> a -> b
$ forall {i}. Integral i => i -> Color
grayAt forall a b. (a -> b) -> a -> b
$ Double -> Double -> Int
getLevel (forall a b. (Real a, Fractional b) => a -> b
realToFrac NominalDiffTime
totalElapsed) (forall a b. (Real a, Fractional b) => a -> b
realToFrac NominalDiffTime
dt)
  , attrBackColor :: MaybeDefault Color
V.attrBackColor = forall v. MaybeDefault v
V.Default
  , attrURL :: MaybeDefault Text
V.attrURL = forall v. MaybeDefault v
V.Default
  }

getLevel :: Double -> Double -> Int
getLevel :: Double -> Double -> Int
getLevel Double
totalElapsed Double
duration = forall a. Ord a => a -> a -> a
min Int
maxGray forall a b. (a -> b) -> a -> b
$ forall a. Ord a => a -> a -> a
max Int
minGray forall a b. (a -> b) -> a -> b
$ forall a b. (RealFrac a, Integral b) => a -> b
round (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
minGray forall a. Num a => a -> a -> a
+ (Double
intensity forall a. Num a => a -> a -> a
* (forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int
maxGray forall a. Num a => a -> a -> a
- Int
minGray))))
  where
    Double
intensity :: Double = forall a. Floating a => a -> a -> a
logBase (Double
totalElapsed forall a. Num a => a -> a -> a
+ Double
1) (Double
duration forall a. Num a => a -> a -> a
+ Double
1)