-- | This module exports time related services.
--
-- @since 0.1
module Pythia.Services.Time
  ( -- * Queries
    queryLocalTime,
    queryUTC,
    queryTimeZone,
    queryTimeZoneLabel,

    -- * Types
    ZonedTime (..),
    UTCTime (..),
    TZLabel (..),
  )
where

import Data.Time.Clock (UTCTime (..))
import Data.Time.Conversion
  ( TZDatabase
      ( TZDatabaseLabel,
        TZDatabaseText
      ),
    TZLabel (..),
    ZonedTime,
  )
import Data.Time.Conversion qualified as TimeConv
import Data.Time.LocalTime qualified as LT
import Effects.Time (getSystemZonedTime)
import Pythia.Prelude

-- | Queries current local time.
--
-- @since 0.1
queryLocalTime :: (MonadCatch m, MonadTime m) => m ZonedTime
queryLocalTime :: forall (m :: Type -> Type).
(MonadCatch m, MonadTime m) =>
m ZonedTime
queryLocalTime = Maybe TimeReader -> m ZonedTime
forall (m :: Type -> Type).
(HasCallStack, MonadCatch m, MonadTime m) =>
Maybe TimeReader -> m ZonedTime
TimeConv.readTime Maybe TimeReader
forall a. Maybe a
Nothing
{-# INLINEABLE queryLocalTime #-}

-- | Queries current UTC time.
--
-- @since 0.1
queryUTC :: (MonadTime m) => m UTCTime
queryUTC :: forall (m :: Type -> Type). MonadTime m => m UTCTime
queryUTC = ZonedTime -> UTCTime
LT.zonedTimeToUTC (ZonedTime -> UTCTime) -> m ZonedTime -> m UTCTime
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> m ZonedTime
forall (m :: Type -> Type).
(MonadTime m, HasCallStack) =>
m ZonedTime
getSystemZonedTime
{-# INLINEABLE queryUTC #-}

-- | Queries current time in the given timezone.
--
-- @
-- queryTimeZone "America/New_York"
-- @
--
-- @since 0.1
queryTimeZone :: (MonadCatch m, MonadTime m) => Text -> m ZonedTime
queryTimeZone :: forall (m :: Type -> Type).
(MonadCatch m, MonadTime m) =>
Text -> m ZonedTime
queryTimeZone =
  Maybe TimeReader -> Maybe TZDatabase -> m ZonedTime
forall (m :: Type -> Type).
(HasCallStack, MonadCatch m, MonadTime m) =>
Maybe TimeReader -> Maybe TZDatabase -> m ZonedTime
TimeConv.readConvertTime Maybe TimeReader
forall a. Maybe a
Nothing
    (Maybe TZDatabase -> m ZonedTime)
-> (Text -> Maybe TZDatabase) -> Text -> m ZonedTime
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TZDatabase -> Maybe TZDatabase
forall a. a -> Maybe a
Just
    (TZDatabase -> Maybe TZDatabase)
-> (Text -> TZDatabase) -> Text -> Maybe TZDatabase
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> TZDatabase
TZDatabaseText
{-# INLINEABLE queryTimeZone #-}

-- | Queries current time in the given timezone.
--
-- __Throws:__
--
-- * 'Pythia.Control.Exception.PythiaException': if an error is
-- encountered (e.g. running a command or parse error).
--
-- @since 0.1
queryTimeZoneLabel :: (MonadCatch m, MonadTime m) => TZLabel -> m ZonedTime
queryTimeZoneLabel :: forall (m :: Type -> Type).
(MonadCatch m, MonadTime m) =>
TZLabel -> m ZonedTime
queryTimeZoneLabel =
  Maybe TimeReader -> Maybe TZDatabase -> m ZonedTime
forall (m :: Type -> Type).
(HasCallStack, MonadCatch m, MonadTime m) =>
Maybe TimeReader -> Maybe TZDatabase -> m ZonedTime
TimeConv.readConvertTime Maybe TimeReader
forall a. Maybe a
Nothing
    (Maybe TZDatabase -> m ZonedTime)
-> (TZLabel -> Maybe TZDatabase) -> TZLabel -> m ZonedTime
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TZDatabase -> Maybe TZDatabase
forall a. a -> Maybe a
Just
    (TZDatabase -> Maybe TZDatabase)
-> (TZLabel -> TZDatabase) -> TZLabel -> Maybe TZDatabase
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TZLabel -> TZDatabase
TZDatabaseLabel
{-# INLINEABLE queryTimeZoneLabel #-}