{-# LANGUAGE
    ConstraintKinds
  , FlexibleContexts
  , DeriveGeneric
  #-}

module App.Types where

import Control.Monad.Reader (ReaderT (runReaderT))
import Control.Monad.Catch (Exception)

import System.IO (hPutStr, stderr)
import System.Exit (exitFailure)
import System.Console.Haskeline (InputT, runInputT, defaultSettings)
import Network.Socket (HostName, PortNumber)

import GHC.Generics (Generic)


-- * Config Data

data Env = Env
  { Env -> HostName
envHost    :: HostName
  , Env -> PortNumber
envPort    :: PortNumber
  , Env -> HostName
envPath    :: String
  , Env -> Bool
envSecure  :: Bool
  } deriving (Int -> Env -> ShowS
[Env] -> ShowS
Env -> HostName
forall a.
(Int -> a -> ShowS) -> (a -> HostName) -> ([a] -> ShowS) -> Show a
showList :: [Env] -> ShowS
$cshowList :: [Env] -> ShowS
show :: Env -> HostName
$cshow :: Env -> HostName
showsPrec :: Int -> Env -> ShowS
$cshowsPrec :: Int -> Env -> ShowS
Show, Env -> Env -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Env -> Env -> Bool
$c/= :: Env -> Env -> Bool
== :: Env -> Env -> Bool
$c== :: Env -> Env -> Bool
Eq)


-- * Effects Stack

type AppM = InputT (ReaderT Env IO)

runAppM :: Env -> AppM a -> IO a
runAppM :: forall a. Env -> AppM a -> IO a
runAppM Env
env AppM a
x = forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT (forall (m :: * -> *) a.
(MonadIO m, MonadMask m) =>
Settings m -> InputT m a -> m a
runInputT forall (m :: * -> *). MonadIO m => Settings m
defaultSettings AppM a
x) Env
env


-- * Exceptions

data InitException
  = URIParseException String
  deriving (forall x. Rep InitException x -> InitException
forall x. InitException -> Rep InitException x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep InitException x -> InitException
$cfrom :: forall x. InitException -> Rep InitException x
Generic, Int -> InitException -> ShowS
[InitException] -> ShowS
InitException -> HostName
forall a.
(Int -> a -> ShowS) -> (a -> HostName) -> ([a] -> ShowS) -> Show a
showList :: [InitException] -> ShowS
$cshowList :: [InitException] -> ShowS
show :: InitException -> HostName
$cshow :: InitException -> HostName
showsPrec :: Int -> InitException -> ShowS
$cshowsPrec :: Int -> InitException -> ShowS
Show)

instance Exception InitException


handleInitException :: InitException -> IO a
handleInitException :: forall a. InitException -> IO a
handleInitException InitException
e =
  case InitException
e of
    URIParseException HostName
u -> do
      Handle -> HostName -> IO ()
hPutStr Handle
stderr forall a b. (a -> b) -> a -> b
$ HostName
"Error: not a valid URI string - `" forall a. [a] -> [a] -> [a]
++ HostName
u forall a. [a] -> [a] -> [a]
++ HostName
"`"
      forall a. IO a
exitFailure