{-# LANGUAGE OverloadedStrings #-}

module System.Metrics.Prometheus.Encode.Text.Histogram
       ( encodeHistogram
       ) where


import           Data.ByteString.Builder                    (Builder)
import           Data.List                                  (intersperse)
import qualified Data.Map                                   as Map
import           Data.Monoid                                ((<>))

import           System.Metrics.Prometheus.Encode.Text.MetricId  (encodeDouble,
                                                             encodeInt,
                                                             encodeLabels,
                                                             encodeName,
                                                             newline, space,
                                                             textValue)
import           System.Metrics.Prometheus.Metric.Histogram (HistogramSample (..),
                                                             UpperBound)
import           System.Metrics.Prometheus.MetricId         (MetricId (..),
                                                             addLabel)


encodeHistogram :: MetricId -> HistogramSample -> Builder
encodeHistogram :: MetricId -> HistogramSample -> Builder
encodeHistogram MetricId
mid HistogramSample
histogram
    =  MetricId -> HistogramSample -> Builder
encodeHistogramBuckets MetricId
mid HistogramSample
histogram Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
newline
    Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
n Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
"_sum"   Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
ls Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
space Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Double -> Builder
forall f. RealFloat f => f -> Builder
encodeDouble (HistogramSample -> Double
histSum HistogramSample
histogram) Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
newline
    Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
n Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
"_count" Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
ls Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
space Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Int -> Builder
encodeInt (HistogramSample -> Int
histCount HistogramSample
histogram)
  where
    n :: Builder
n = Name -> Builder
encodeName (Name -> Builder) -> Name -> Builder
forall a b. (a -> b) -> a -> b
$ MetricId -> Name
name MetricId
mid
    ls :: Builder
ls = Labels -> Builder
encodeLabels (Labels -> Builder) -> Labels -> Builder
forall a b. (a -> b) -> a -> b
$ MetricId -> Labels
labels MetricId
mid


encodeHistogramBuckets :: MetricId -> HistogramSample -> Builder
encodeHistogramBuckets :: MetricId -> HistogramSample -> Builder
encodeHistogramBuckets MetricId
mid = [Builder] -> Builder
forall a. Monoid a => [a] -> a
mconcat ([Builder] -> Builder)
-> (HistogramSample -> [Builder]) -> HistogramSample -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> [Builder] -> [Builder]
forall a. a -> [a] -> [a]
intersperse Builder
newline ([Builder] -> [Builder])
-> (HistogramSample -> [Builder]) -> HistogramSample -> [Builder]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Double, Builder) -> Builder) -> [(Double, Builder)] -> [Builder]
forall a b. (a -> b) -> [a] -> [b]
map (Double, Builder) -> Builder
forall a b. (a, b) -> b
snd ([(Double, Builder)] -> [Builder])
-> (HistogramSample -> [(Double, Builder)])
-> HistogramSample
-> [Builder]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Map Double Builder -> [(Double, Builder)]
forall k a. Map k a -> [(k, a)]
Map.toList
    (Map Double Builder -> [(Double, Builder)])
-> (HistogramSample -> Map Double Builder)
-> HistogramSample
-> [(Double, Builder)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Double -> Double -> Builder)
-> Map Double Double -> Map Double Builder
forall k a b. (k -> a -> b) -> Map k a -> Map k b
Map.mapWithKey (MetricId -> Double -> Double -> Builder
encodeHistogramBucket MetricId
mid) (Map Double Double -> Map Double Builder)
-> (HistogramSample -> Map Double Double)
-> HistogramSample
-> Map Double Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HistogramSample -> Map Double Double
histBuckets


encodeHistogramBucket :: MetricId -> UpperBound -> Double -> Builder
encodeHistogramBucket :: MetricId -> Double -> Double -> Builder
encodeHistogramBucket MetricId
mid Double
upperBound Double
count
    = Name -> Builder
encodeName (MetricId -> Name
name MetricId
mid) Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
"_bucket" Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Labels -> Builder
encodeLabels Labels
labels' Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
space Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Double -> Builder
forall f. RealFloat f => f -> Builder
encodeDouble Double
count
  where
    labels' :: Labels
labels' = Text -> Text -> Labels -> Labels
addLabel Text
"le" (Double -> Text
forall f. RealFloat f => f -> Text
textValue Double
upperBound) (MetricId -> Labels
labels MetricId
mid)