{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE ViewPatterns #-}

-- | This module provides toml configuration for the battery percentage service.
module Navi.Services.Battery.Percentage.Toml
  ( BatteryPercentageToml (..),
    BatteryPercentageNoteToml (..),
  )
where

import DBus.Notify (UrgencyLevel)
import Navi.Data.NaviNote (Timeout, timeoutOptDecoder)
import Navi.Data.PollInterval (PollInterval, pollIntervalOptDecoder)
import Navi.Event.Toml
  ( ErrorNoteToml,
    RepeatEventToml,
    errorNoteOptDecoder,
    repeatEventOptDecoder,
  )
import Navi.Prelude
import Navi.Services.Battery.Common (batteryAppDecoder)
import Navi.Utils (urgencyLevelOptDecoder)
import Numeric.Data.Interval qualified as Interval
import Pythia.Services.Battery (BatteryApp (..), Percentage (..))

-- | TOML for each individual battery percentage.
data BatteryPercentageNoteToml = MkBatteryPercentageNoteToml
  { -- | The percentage for this alert.
    BatteryPercentageNoteToml -> Percentage
percentage :: Percentage,
    -- | The urgency for this alert.
    BatteryPercentageNoteToml -> Maybe UrgencyLevel
urgency :: Maybe UrgencyLevel,
    -- | The timeout for this alert.
    BatteryPercentageNoteToml -> Maybe Timeout
mTimeout :: Maybe Timeout
  }
  deriving stock (BatteryPercentageNoteToml -> BatteryPercentageNoteToml -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: BatteryPercentageNoteToml -> BatteryPercentageNoteToml -> Bool
$c/= :: BatteryPercentageNoteToml -> BatteryPercentageNoteToml -> Bool
== :: BatteryPercentageNoteToml -> BatteryPercentageNoteToml -> Bool
$c== :: BatteryPercentageNoteToml -> BatteryPercentageNoteToml -> Bool
Eq, Int -> BatteryPercentageNoteToml -> ShowS
[BatteryPercentageNoteToml] -> ShowS
BatteryPercentageNoteToml -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [BatteryPercentageNoteToml] -> ShowS
$cshowList :: [BatteryPercentageNoteToml] -> ShowS
show :: BatteryPercentageNoteToml -> String
$cshow :: BatteryPercentageNoteToml -> String
showsPrec :: Int -> BatteryPercentageNoteToml -> ShowS
$cshowsPrec :: Int -> BatteryPercentageNoteToml -> ShowS
Show)

makeFieldLabelsNoPrefix ''BatteryPercentageNoteToml

-- | @since 0.1
instance DecodeTOML BatteryPercentageNoteToml where
  tomlDecoder :: Decoder BatteryPercentageNoteToml
tomlDecoder =
    Percentage
-> Maybe UrgencyLevel -> Maybe Timeout -> BatteryPercentageNoteToml
MkBatteryPercentageNoteToml
      forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Decoder Percentage
percentageDecoder
      forall (f :: Type -> Type) a b.
Applicative f =>
f (a -> b) -> f a -> f b
<*> Decoder (Maybe UrgencyLevel)
urgencyLevelOptDecoder
      forall (f :: Type -> Type) a b.
Applicative f =>
f (a -> b) -> f a -> f b
<*> Decoder (Maybe Timeout)
timeoutOptDecoder

percentageDecoder :: Decoder Percentage
percentageDecoder :: Decoder Percentage
percentageDecoder = forall a. Decoder a -> Text -> Decoder a
getFieldWith Decoder Percentage
decoder Text
"percent"
  where
    decoder :: Decoder Percentage
decoder =
      forall a. DecodeTOML a => Decoder a
tomlDecoder forall (m :: Type -> Type) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Word8
x ->
        case Word8 -> Maybe Percentage
mkPercentage Word8
x of
          Just Percentage
n -> forall (f :: Type -> Type) a. Applicative f => a -> f a
pure Percentage
n
          Maybe Percentage
Nothing ->
            forall (m :: Type -> Type) a. MonadFail m => String -> m a
fail forall a b. (a -> b) -> a -> b
$
              Text -> String
unpack forall a b. (a -> b) -> a -> b
$
                [Text] -> Text
concat
                  [ Text
"Unexpected percent: ",
                    forall a. Show a => a -> Text
showt Word8
x,
                    Text
". Expected integer in [0, 100]."
                  ]
    mkPercentage :: Word8 -> Maybe Percentage
mkPercentage = forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap LRInterval 0 100 Word8 -> Percentage
MkPercentage forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (l :: Nat) (r :: Nat) a.
(KnownNat l, KnownNat r, Num a, Ord a) =>
a -> Maybe (LRInterval l r a)
Interval.mkLRInterval

-- | TOML for the battery percentage service.
data BatteryPercentageToml = MkBatteryPercentageToml
  { -- | All alerts for this service.
    BatteryPercentageToml -> NonEmpty BatteryPercentageNoteToml
alerts :: NonEmpty BatteryPercentageNoteToml,
    -- | The poll interval.
    BatteryPercentageToml -> Maybe PollInterval
pollInterval :: Maybe PollInterval,
    -- | Determines how we treat repeat alerts.
    BatteryPercentageToml -> Maybe RepeatEventToml
repeatEvent :: Maybe RepeatEventToml,
    -- | Determines how we handle errors.
    BatteryPercentageToml -> Maybe ErrorNoteToml
errorNote :: Maybe ErrorNoteToml,
    -- | Determines how we should query the system for battery information.
    BatteryPercentageToml -> BatteryApp
app :: BatteryApp
  }
  deriving stock (BatteryPercentageToml -> BatteryPercentageToml -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: BatteryPercentageToml -> BatteryPercentageToml -> Bool
$c/= :: BatteryPercentageToml -> BatteryPercentageToml -> Bool
== :: BatteryPercentageToml -> BatteryPercentageToml -> Bool
$c== :: BatteryPercentageToml -> BatteryPercentageToml -> Bool
Eq, Int -> BatteryPercentageToml -> ShowS
[BatteryPercentageToml] -> ShowS
BatteryPercentageToml -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [BatteryPercentageToml] -> ShowS
$cshowList :: [BatteryPercentageToml] -> ShowS
show :: BatteryPercentageToml -> String
$cshow :: BatteryPercentageToml -> String
showsPrec :: Int -> BatteryPercentageToml -> ShowS
$cshowsPrec :: Int -> BatteryPercentageToml -> ShowS
Show)

makeFieldLabelsNoPrefix ''BatteryPercentageToml

-- | @since 0.1
instance DecodeTOML BatteryPercentageToml where
  tomlDecoder :: Decoder BatteryPercentageToml
tomlDecoder =
    NonEmpty BatteryPercentageNoteToml
-> Maybe PollInterval
-> Maybe RepeatEventToml
-> Maybe ErrorNoteToml
-> BatteryApp
-> BatteryPercentageToml
MkBatteryPercentageToml
      forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Decoder a -> Text -> Decoder a
getFieldWith forall a. DecodeTOML a => Decoder a
tomlDecoder Text
"alert"
      forall (f :: Type -> Type) a b.
Applicative f =>
f (a -> b) -> f a -> f b
<*> Decoder (Maybe PollInterval)
pollIntervalOptDecoder
      forall (f :: Type -> Type) a b.
Applicative f =>
f (a -> b) -> f a -> f b
<*> Decoder (Maybe RepeatEventToml)
repeatEventOptDecoder
      forall (f :: Type -> Type) a b.
Applicative f =>
f (a -> b) -> f a -> f b
<*> Decoder (Maybe ErrorNoteToml)
errorNoteOptDecoder
      forall (f :: Type -> Type) a b.
Applicative f =>
f (a -> b) -> f a -> f b
<*> forall a. Decoder a -> Text -> Decoder a
getFieldWith Decoder BatteryApp
batteryAppDecoder Text
"app"