{-# LANGUAGE UndecidableInstances #-}

-- | Provides environment for usage with AppleScript.
module Navi.Env.AppleScript
  ( mkAppleScriptEnv,
    naviToAppleScript,
  )
where

import Navi.Config.Types (Config, NoteSystem (AppleScript))
import Navi.Data.NaviLog (LogEnv)
import Navi.Data.NaviNote (NaviNote)
import Navi.Env.Core (Env (MkEnv, events, logEnv, noteQueue, notifySystem))
import Navi.Prelude

-- | Creates a 'AppleScriptEnv' from the provided log types and configuration
-- data.
mkAppleScriptEnv ::
  (MonadSTM m) =>
  Maybe LogEnv ->
  Config ->
  m Env
mkAppleScriptEnv :: forall (m :: Type -> Type).
MonadSTM m =>
Maybe LogEnv -> Config -> m Env
mkAppleScriptEnv Maybe LogEnv
logEnv Config
config = do
  TBQueue NaviNote
noteQueue <- Natural -> m (TBQueue NaviNote)
forall (m :: Type -> Type) a.
(HasCallStack, MonadSTM m) =>
Natural -> m (TBQueue a)
newTBQueueA Natural
1000
  pure
    $ MkEnv
      { events :: NonEmpty AnyEvent
events = Config
config Config
-> Optic' A_Lens NoIx Config (NonEmpty AnyEvent)
-> NonEmpty AnyEvent
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens NoIx Config (NonEmpty AnyEvent)
#events,
        Maybe LogEnv
logEnv :: Maybe LogEnv
logEnv :: Maybe LogEnv
logEnv,
        TBQueue NaviNote
noteQueue :: TBQueue NaviNote
noteQueue :: TBQueue NaviNote
noteQueue,
        notifySystem :: NoteSystem 'ConfigPhaseEnv
notifySystem = NoteSystem 'ConfigPhaseEnv
forall (p :: ConfigPhase). NoteSystem p
AppleScript
      }
{-# INLINEABLE mkAppleScriptEnv #-}

-- | Turns a 'NaviNote' into a string to be sent with the notify-send tool.
naviToAppleScript :: NaviNote -> Text
naviToAppleScript :: NaviNote -> Text
naviToAppleScript NaviNote
naviNote = Text
txt
  where
    txt :: Text
txt =
      [Text] -> Text
forall a. Monoid a => [a] -> a
mconcat
        [ Text
"osascript -e 'display notification ",
          Text -> (Text -> Text) -> Maybe Text -> Text
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Text
"" Text -> Text
withDoubleQuotes (NaviNote
naviNote NaviNote -> Optic' A_Lens NoIx NaviNote (Maybe Text) -> Maybe Text
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens NoIx NaviNote (Maybe Text)
#body),
          Text
" with title \"Navi\" ",
          Text
" subtitle ",
          Text -> Text
withDoubleQuotes (NaviNote
naviNote NaviNote -> Optic' A_Lens NoIx NaviNote Text -> Text
forall k s (is :: IxList) a.
Is k A_Getter =>
s -> Optic' k is s a -> a
^. Optic' A_Lens NoIx NaviNote Text
#summary),
          Text
"'"
        ]

withDoubleQuotes :: Text -> Text
withDoubleQuotes :: Text -> Text
withDoubleQuotes Text
s = Text
" \"" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
s Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"\" "