-- | This module provides a service for alerts related to battery statuses.
module Navi.Services.Battery.Status
  ( BatteryStatusToml,
    toEvent,
  )
where

import Navi.Data.NaviNote (NaviNote, Timeout)
import Navi.Data.NaviNote qualified as NNote
import Navi.Data.PollInterval (PollInterval (..))
import Navi.Event.Toml qualified as EventToml
import Navi.Event.Types
  ( AnyEvent (..),
    ErrorNote (..),
    Event (..),
    RepeatEvent (..),
  )
import Navi.Prelude
import Navi.Services.Battery.Status.Toml (BatteryStatusToml)
import Navi.Services.Types (ServiceType (..))
import Pythia.Services.Battery (BatteryApp, BatteryStatus (..))

-- | Transforms toml configuration data into an 'AnyEvent'.
toEvent ::
  (MonadIORef m) =>
  BatteryStatusToml ->
  m AnyEvent
toEvent :: forall (m :: Type -> Type).
MonadIORef m =>
BatteryStatusToml -> m AnyEvent
toEvent BatteryStatusToml
toml = do
  RepeatEvent BatteryStatus
repeatEvent <- forall (m :: Type -> Type) a.
MonadIORef m =>
Maybe RepeatEventToml -> m (RepeatEvent a)
EventToml.mRepeatEventTomlToVal forall a b. (a -> b) -> a -> b
$ BatteryStatusToml
toml forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. forall a. IsLabel "repeatEvent" a => a
#repeatEvent
  ErrorNote
errorNote <- forall (m :: Type -> Type).
MonadIORef m =>
Maybe ErrorNoteToml -> m ErrorNote
EventToml.mErrorNoteTomlToVal forall a b. (a -> b) -> a -> b
$ BatteryStatusToml
toml forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. forall a. IsLabel "errorNote" a => a
#errorNote
  let evt :: Event BatteryStatus
evt = Maybe Timeout
-> BatteryApp
-> PollInterval
-> RepeatEvent BatteryStatus
-> ErrorNote
-> Event BatteryStatus
mkStatusEvent Maybe Timeout
to BatteryApp
cfg PollInterval
pi RepeatEvent BatteryStatus
repeatEvent ErrorNote
errorNote
  forall (f :: Type -> Type) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall result. (Eq result, Show result) => Event result -> AnyEvent
MkAnyEvent Event BatteryStatus
evt
  where
    cfg :: BatteryApp
cfg = BatteryStatusToml
toml forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. forall a. IsLabel "app" a => a
#app
    to :: Maybe Timeout
to = BatteryStatusToml
toml forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. forall a. IsLabel "mTimeout" a => a
#mTimeout
    pi :: PollInterval
pi = forall a. a -> Maybe a -> a
fromMaybe (Natural -> PollInterval
MkPollInterval Natural
30) (BatteryStatusToml
toml forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. forall a. IsLabel "pollInterval" a => a
#pollInterval)
{-# INLINEABLE toEvent #-}

mkStatusEvent ::
  Maybe Timeout ->
  BatteryApp ->
  PollInterval ->
  RepeatEvent BatteryStatus ->
  ErrorNote ->
  Event BatteryStatus
mkStatusEvent :: Maybe Timeout
-> BatteryApp
-> PollInterval
-> RepeatEvent BatteryStatus
-> ErrorNote
-> Event BatteryStatus
mkStatusEvent Maybe Timeout
to BatteryApp
cfg PollInterval
pi RepeatEvent BatteryStatus
repeatEvent ErrorNote
errorNote =
  MkEvent
    { $sel:name:MkEvent :: Text
name = Text
"battery-status",
      $sel:serviceType:MkEvent :: ServiceType BatteryStatus
serviceType = BatteryApp -> ServiceType BatteryStatus
BatteryStatus BatteryApp
cfg,
      $sel:pollInterval:MkEvent :: PollInterval
pollInterval = PollInterval
pi,
      $sel:raiseAlert:MkEvent :: BatteryStatus -> Maybe NaviNote
raiseAlert = Maybe Timeout -> BatteryStatus -> Maybe NaviNote
toNote Maybe Timeout
to,
      $sel:repeatEvent:MkEvent :: RepeatEvent BatteryStatus
repeatEvent = RepeatEvent BatteryStatus
repeatEvent,
      $sel:errorNote:MkEvent :: ErrorNote
errorNote = ErrorNote
errorNote
    }
{-# INLINEABLE mkStatusEvent #-}

toNote :: Maybe Timeout -> BatteryStatus -> Maybe NaviNote
toNote :: Maybe Timeout -> BatteryStatus -> Maybe NaviNote
toNote Maybe Timeout
timeout BatteryStatus
status = Maybe Timeout -> Text -> Maybe NaviNote
toNote' Maybe Timeout
timeout forall a b. (a -> b) -> a -> b
$ forall {a}. IsString a => BatteryStatus -> a
fromStatus BatteryStatus
status
  where
    fromStatus :: BatteryStatus -> a
fromStatus BatteryStatus
Charging = a
"Battery charging"
    fromStatus BatteryStatus
Discharging = a
"Battery discharging"
    fromStatus BatteryStatus
Full = a
"Battery full"
    fromStatus BatteryStatus
Pending = a
"Battery pending"
{-# INLINEABLE toNote #-}

toNote' :: Maybe Timeout -> Text -> Maybe NaviNote
toNote' :: Maybe Timeout -> Text -> Maybe NaviNote
toNote' Maybe Timeout
timeout Text
msg =
  forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$
    NNote.MkNaviNote
      { $sel:summary:MkNaviNote :: Text
NNote.summary = Text
"Battery Status",
        $sel:body:MkNaviNote :: Maybe Text
NNote.body = forall a. a -> Maybe a
Just Text
msg,
        $sel:urgency:MkNaviNote :: Maybe UrgencyLevel
NNote.urgency = forall a. Maybe a
Nothing,
        $sel:timeout:MkNaviNote :: Maybe Timeout
NNote.timeout = Maybe Timeout
timeout
      }
{-# INLINEABLE toNote' #-}