{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
module Honeycomb.API.Types where

import Chronos
    ( builder_YmdHMS,
      timeToDatetime,
      w3c,
      Datetime,
      SubsecondPrecision(SubsecondPrecisionFixed),
      Time )
import Data.Aeson
import Data.Maybe
import Data.Text (Text)
import qualified Data.Text.Lazy as LT
import qualified Data.Text.Lazy.Builder as TB
import Data.Word

data Event = Event
  { Event -> Maybe Word64
eventSampleRate :: !(Maybe Word64)
  , Event -> Maybe Time
eventTimestamp :: !(Maybe Time)
  , Event -> Object
eventData :: !Object
  }

instance ToJSON Event where
  toJSON :: Event -> Value
toJSON Event{Maybe Word64
Maybe Time
Object
eventData :: Object
eventTimestamp :: Maybe Time
eventSampleRate :: Maybe Word64
eventData :: Event -> Object
eventTimestamp :: Event -> Maybe Time
eventSampleRate :: Event -> Maybe Word64
..} = [Pair] -> Value
object ([Pair] -> Value) -> [Pair] -> Value
forall a b. (a -> b) -> a -> b
$ (Text
"data" Text -> Object -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Object
eventData) Pair -> [Pair] -> [Pair]
forall a. a -> [a] -> [a]
: [Maybe Pair] -> [Pair]
forall a. [Maybe a] -> [a]
catMaybes
    [ (\Time
x -> Text
"time" Text -> Text -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Datetime -> Text
encodeRFC3339 (Time -> Datetime
timeToDatetime Time
x)) (Time -> Pair) -> Maybe Time -> Maybe Pair
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Time
eventTimestamp
    , (Text
"samplerate" Text -> Word64 -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.=) (Word64 -> Pair) -> Maybe Word64 -> Maybe Pair
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Word64
eventSampleRate
    ]
  toEncoding :: Event -> Encoding
toEncoding Event{Maybe Word64
Maybe Time
Object
eventData :: Object
eventTimestamp :: Maybe Time
eventSampleRate :: Maybe Word64
eventData :: Event -> Object
eventTimestamp :: Event -> Maybe Time
eventSampleRate :: Event -> Maybe Word64
..} = Series -> Encoding
pairs (Series -> Encoding) -> Series -> Encoding
forall a b. (a -> b) -> a -> b
$ [Series] -> Series
forall a. Monoid a => [a] -> a
mconcat
    [ Text
"data" Text -> Object -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Object
eventData
    , Series -> (Time -> Series) -> Maybe Time -> Series
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Series
forall a. Monoid a => a
mempty (\Time
x -> Text
"time" Text -> Text -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Datetime -> Text
encodeRFC3339 (Time -> Datetime
timeToDatetime Time
x)) Maybe Time
eventTimestamp
    , Series -> (Word64 -> Series) -> Maybe Word64 -> Series
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Series
forall a. Monoid a => a
mempty (Text
"samplerate" Text -> Word64 -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.=) Maybe Word64
eventSampleRate
    ]

-- | Construct a 'Text' 'TB.Builder' corresponding to the ISO-8601
--   encoding of the given 'Datetime'.
builderRFC3339 :: Datetime -> TB.Builder
builderRFC3339 :: Datetime -> Builder
builderRFC3339 Datetime
dt = SubsecondPrecision -> DatetimeFormat -> Datetime -> Builder
builder_YmdHMS (Int -> SubsecondPrecision
SubsecondPrecisionFixed Int
8) DatetimeFormat
w3c Datetime
dt Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
"Z"

-- | Construct 'Text' corresponding to the ISO-8601
--   encoding of the given 'Datetime'.
encodeRFC3339 :: Datetime -> Text
encodeRFC3339 :: Datetime -> Text
encodeRFC3339 = Text -> Text
LT.toStrict (Text -> Text) -> (Datetime -> Text) -> Datetime -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> Text
TB.toLazyText (Builder -> Text) -> (Datetime -> Builder) -> Datetime -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Datetime -> Builder
builderRFC3339