-- |Reader Interpreter for InstanceName, Internal
module Helic.Interpreter.InstanceName where

import Network.HostName (getHostName)
import qualified Polysemy.Error as Polysemy
import Polysemy.Reader (runReader)

import Helic.Data.InstanceName (InstanceName (InstanceName))

-- |If no instance name was given in the config file, query the system's host name.
determineName ::
  Members [Error Text, Embed IO] r =>
  Maybe Text ->
  Sem r InstanceName
determineName :: Maybe Text -> Sem r InstanceName
determineName = \case
  Just Text
name ->
    InstanceName -> Sem r InstanceName
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> InstanceName
InstanceName Text
name)
  Maybe Text
_ ->
    (SomeException -> Text) -> IO InstanceName -> Sem r InstanceName
forall exc err (r :: EffectRow) a.
(Exception exc, Member (Error err) r, Member (Embed IO) r) =>
(exc -> err) -> IO a -> Sem r a
Polysemy.fromExceptionVia SomeException -> Text
forall a. (Exon ExonDefault a, IsString a) => SomeException -> a
err (String -> InstanceName
forall a. IsString a => String -> a
fromString (String -> InstanceName) -> IO String -> IO InstanceName
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IO String
getHostName)
  where
    err :: SomeException -> a
err (SomeException
e :: SomeException) =
      [exon|no name in conig and unable to determine hostname: #{show e}|]

-- |Interpret @'Reader' 'InstanceName'@ using the name specified in the config file, falling back to the system's host
-- name if it wasn't given.
interpretInstanceName ::
  Members [Error Text, Embed IO] r =>
  Maybe Text ->
  InterpreterFor (Reader InstanceName) r
interpretInstanceName :: Maybe Text -> InterpreterFor (Reader InstanceName) r
interpretInstanceName Maybe Text
configName Sem (Reader InstanceName : r) a
sem = do
  InstanceName
name <- Maybe Text -> Sem r InstanceName
forall (r :: EffectRow).
Members '[Error Text, Embed IO] r =>
Maybe Text -> Sem r InstanceName
determineName Maybe Text
configName
  InstanceName -> Sem (Reader InstanceName : r) a -> Sem r a
forall i (r :: EffectRow) a. i -> Sem (Reader i : r) a -> Sem r a
runReader InstanceName
name Sem (Reader InstanceName : r) a
sem