module Freckle.App.Scientist
  ( experimentPublishDatadog
  ) where

import Freckle.App.Prelude

import Freckle.App.Stats (HasStatsClient)
import qualified Freckle.App.Stats as Stats
import Scientist
import Scientist.Duration

-- | Publish experiment durations using "Freckle.App.Stats"
--
-- * Experiments are labeled "science.${name}"
-- * Results are tagged with "variant:${name}"
experimentPublishDatadog
  :: (MonadReader env m, MonadUnliftIO m, HasStatsClient env)
  => Result c a b
  -> m ()
experimentPublishDatadog :: forall env (m :: * -> *) c a b.
(MonadReader env m, MonadUnliftIO m, HasStatsClient env) =>
Result c a b -> m ()
experimentPublishDatadog Result c a b
result = forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ (forall c a b. Result c a b -> Maybe (ResultDetails c a b)
resultDetails Result c a b
result) forall a b. (a -> b) -> a -> b
$ \ResultDetails c a b
details -> do
  let
    statName :: Text
statName = Text
"science." forall a. Semigroup a => a -> a -> a
<> forall c a b. ResultDetails c a b -> Text
resultDetailsExperimentName ResultDetails c a b
details
    ResultControl {a
Text
Duration
resultControlName :: forall a. ResultControl a -> Text
resultControlValue :: forall a. ResultControl a -> a
resultControlDuration :: forall a. ResultControl a -> Duration
resultControlDuration :: Duration
resultControlValue :: a
resultControlName :: Text
..} = forall c a b. ResultDetails c a b -> ResultControl a
resultDetailsControl ResultDetails c a b
details

  forall env (m :: * -> *) a.
(MonadReader env m, HasStatsClient env) =>
[(Text, Text)] -> m a -> m a
Stats.tagged [(Text
"variant", Text
resultControlName)] forall a b. (a -> b) -> a -> b
$
    forall (m :: * -> *) env.
(MonadUnliftIO m, MonadReader env m, HasStatsClient env) =>
Text -> Double -> m ()
Stats.gauge Text
statName forall a b. (a -> b) -> a -> b
$
      Duration -> Double
durationToSeconds Duration
resultControlDuration

  forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ (forall c a b. ResultDetails c a b -> NonEmpty (ResultCandidate b)
resultDetailsCandidates ResultDetails c a b
details) forall a b. (a -> b) -> a -> b
$ \ResultCandidate {Either SomeException b
Text
Duration
resultCandidateName :: forall a. ResultCandidate a -> Text
resultCandidateValue :: forall a. ResultCandidate a -> Either SomeException a
resultCandidateDuration :: forall a. ResultCandidate a -> Duration
resultCandidateDuration :: Duration
resultCandidateValue :: Either SomeException b
resultCandidateName :: Text
..} ->
    forall env (m :: * -> *) a.
(MonadReader env m, HasStatsClient env) =>
[(Text, Text)] -> m a -> m a
Stats.tagged [(Text
"variant", Text
"candidate-" forall a. Semigroup a => a -> a -> a
<> Text
resultCandidateName)] forall a b. (a -> b) -> a -> b
$
      forall (m :: * -> *) env.
(MonadUnliftIO m, MonadReader env m, HasStatsClient env) =>
Text -> Double -> m ()
Stats.gauge Text
statName forall a b. (a -> b) -> a -> b
$
        Duration -> Double
durationToSeconds Duration
resultCandidateDuration