-- | Utility functions for making common actions easier.
module Strive.Utilities
  ( with
  -- * Streams
  , altitudeStream
  , cadenceStream
  , distanceStream
  , gradeSmoothStream
  , heartrateStream
  , latlngStream
  , movingStream
  , tempStream
  , timeStream
  , velocitySmoothStream
  , wattsStream
  ) where

import Data.Aeson (FromJSON, Result(Error, Success), Value, fromJSON)
import Data.Default (Default, def)
import Data.Maybe (mapMaybe)
import Data.Text (pack)
import qualified Strive.Enums as Enums
import Strive.Types (StreamDetailed, streamDetailed_data, streamDetailed_type)

-- | Modify an action's default options by listing changes to it.
with :: Default a => [a -> a] -> a
with :: [a -> a] -> a
with = ((a -> a) -> a -> a) -> a -> [a -> a] -> a
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (a -> a) -> a -> a
forall a b. (a -> b) -> a -> b
($) a
forall a. Default a => a
def

altitudeStream :: StreamDetailed -> Maybe [Double]
altitudeStream :: StreamDetailed -> Maybe [Double]
altitudeStream = StreamType -> StreamDetailed -> Maybe [Double]
forall a. FromJSON a => StreamType -> StreamDetailed -> Maybe [a]
lookupStream StreamType
Enums.AltitudeStream

cadenceStream :: StreamDetailed -> Maybe [Integer]
cadenceStream :: StreamDetailed -> Maybe [Integer]
cadenceStream = StreamType -> StreamDetailed -> Maybe [Integer]
forall a. FromJSON a => StreamType -> StreamDetailed -> Maybe [a]
lookupStream StreamType
Enums.CadenceStream

distanceStream :: StreamDetailed -> Maybe [Double]
distanceStream :: StreamDetailed -> Maybe [Double]
distanceStream = StreamType -> StreamDetailed -> Maybe [Double]
forall a. FromJSON a => StreamType -> StreamDetailed -> Maybe [a]
lookupStream StreamType
Enums.DistanceStream

gradeSmoothStream :: StreamDetailed -> Maybe [Double]
gradeSmoothStream :: StreamDetailed -> Maybe [Double]
gradeSmoothStream = StreamType -> StreamDetailed -> Maybe [Double]
forall a. FromJSON a => StreamType -> StreamDetailed -> Maybe [a]
lookupStream StreamType
Enums.GradeSmoothStream

heartrateStream :: StreamDetailed -> Maybe [Integer]
heartrateStream :: StreamDetailed -> Maybe [Integer]
heartrateStream = StreamType -> StreamDetailed -> Maybe [Integer]
forall a. FromJSON a => StreamType -> StreamDetailed -> Maybe [a]
lookupStream StreamType
Enums.HeartrateStream

latlngStream :: StreamDetailed -> Maybe [(Double, Double)]
latlngStream :: StreamDetailed -> Maybe [(Double, Double)]
latlngStream = StreamType -> StreamDetailed -> Maybe [(Double, Double)]
forall a. FromJSON a => StreamType -> StreamDetailed -> Maybe [a]
lookupStream StreamType
Enums.LatlngStream

movingStream :: StreamDetailed -> Maybe [Bool]
movingStream :: StreamDetailed -> Maybe [Bool]
movingStream = StreamType -> StreamDetailed -> Maybe [Bool]
forall a. FromJSON a => StreamType -> StreamDetailed -> Maybe [a]
lookupStream StreamType
Enums.MovingStream

tempStream :: StreamDetailed -> Maybe [Integer]
tempStream :: StreamDetailed -> Maybe [Integer]
tempStream = StreamType -> StreamDetailed -> Maybe [Integer]
forall a. FromJSON a => StreamType -> StreamDetailed -> Maybe [a]
lookupStream StreamType
Enums.TempStream

timeStream :: StreamDetailed -> Maybe [Integer]
timeStream :: StreamDetailed -> Maybe [Integer]
timeStream = StreamType -> StreamDetailed -> Maybe [Integer]
forall a. FromJSON a => StreamType -> StreamDetailed -> Maybe [a]
lookupStream StreamType
Enums.TimeStream

velocitySmoothStream :: StreamDetailed -> Maybe [Double]
velocitySmoothStream :: StreamDetailed -> Maybe [Double]
velocitySmoothStream = StreamType -> StreamDetailed -> Maybe [Double]
forall a. FromJSON a => StreamType -> StreamDetailed -> Maybe [a]
lookupStream StreamType
Enums.VelocitySmoothStream

wattsStream :: StreamDetailed -> Maybe [Integer]
wattsStream :: StreamDetailed -> Maybe [Integer]
wattsStream = StreamType -> StreamDetailed -> Maybe [Integer]
forall a. FromJSON a => StreamType -> StreamDetailed -> Maybe [a]
lookupStream StreamType
Enums.WattsStream

lookupStream :: FromJSON a => Enums.StreamType -> StreamDetailed -> Maybe [a]
lookupStream :: StreamType -> StreamDetailed -> Maybe [a]
lookupStream StreamType
streamType StreamDetailed
stream =
  if StreamDetailed -> Text
streamDetailed_type StreamDetailed
stream Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== String -> Text
pack (StreamType -> String
forall a. Show a => a -> String
show StreamType
streamType)
    then [a] -> Maybe [a]
forall a. a -> Maybe a
Just ((Value -> Maybe a) -> [Value] -> [a]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe Value -> Maybe a
forall a. FromJSON a => Value -> Maybe a
maybeFromJson (StreamDetailed -> [Value]
streamDetailed_data StreamDetailed
stream))
    else Maybe [a]
forall a. Maybe a
Nothing

maybeFromJson :: FromJSON a => Value -> Maybe a
maybeFromJson :: Value -> Maybe a
maybeFromJson Value
value = case Value -> Result a
forall a. FromJSON a => Value -> Result a
fromJSON Value
value of
  Success a
x -> a -> Maybe a
forall a. a -> Maybe a
Just a
x
  Error String
_ -> Maybe a
forall a. Maybe a
Nothing