{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE NumericUnderscores #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE UnicodeSyntax #-}
{-# LANGUAGE LambdaCase #-}

-- | Application’s command-line interface
module MatrixBot.Options where

import Data.Text (Text, pack)
import Data.UUID (fromString)
import qualified Data.Attoparsec.Text as AP
import Data.List (find, intercalate)
import Control.Monad.IO.Class
import qualified Control.Monad.Logger as ML
import Options.Applicative
import MatrixBot.SharedTypes


-- * Commands, options, and their specs

data AppCommand
  = AppCommandAuth AuthOptions
  | AppCommandStart StartOptions
  | AppCommandSendMessage SendMessageOptions
  | AppCommandEditMessage EditMessageOptions

appCommandParserInfo  ParserInfo AppCommand
appCommandParserInfo :: ParserInfo AppCommand
appCommandParserInfo
  = Parser AppCommand -> InfoMod AppCommand -> ParserInfo AppCommand
forall a. Parser a -> InfoMod a -> ParserInfo a
info (Parser (AppCommand -> AppCommand)
forall a. Parser (a -> a)
helper Parser (AppCommand -> AppCommand)
-> Parser AppCommand -> Parser AppCommand
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser AppCommand
appCommandParser)
  (InfoMod AppCommand -> ParserInfo AppCommand)
-> InfoMod AppCommand -> ParserInfo AppCommand
forall a b. (a -> b) -> a -> b
$ InfoMod AppCommand
forall a. InfoMod a
fullDesc InfoMod AppCommand -> InfoMod AppCommand -> InfoMod AppCommand
forall a. Semigroup a => a -> a -> a
<> [Char] -> InfoMod AppCommand
forall a. [Char] -> InfoMod a
header [Char]
"matrix-bot - Matrix multipurpose bot"

appCommandParser  Parser AppCommand
appCommandParser :: Parser AppCommand
appCommandParser = Parser AppCommand
go where
  go :: Parser AppCommand
go = Mod CommandFields AppCommand -> Parser AppCommand
forall a. Mod CommandFields a -> Parser a
hsubparser (Mod CommandFields AppCommand -> Parser AppCommand)
-> Mod CommandFields AppCommand -> Parser AppCommand
forall a b. (a -> b) -> a -> b
$ Mod CommandFields AppCommand
authCommand Mod CommandFields AppCommand
-> Mod CommandFields AppCommand -> Mod CommandFields AppCommand
forall a. Semigroup a => a -> a -> a
<> Mod CommandFields AppCommand
startCommand Mod CommandFields AppCommand
-> Mod CommandFields AppCommand -> Mod CommandFields AppCommand
forall a. Semigroup a => a -> a -> a
<> Mod CommandFields AppCommand
sendMessageCommand Mod CommandFields AppCommand
-> Mod CommandFields AppCommand -> Mod CommandFields AppCommand
forall a. Semigroup a => a -> a -> a
<> Mod CommandFields AppCommand
editMessageCommand

  authCommand  Mod CommandFields AppCommand
  authCommand :: Mod CommandFields AppCommand
authCommand
    = [Char] -> ParserInfo AppCommand -> Mod CommandFields AppCommand
forall a. [Char] -> ParserInfo a -> Mod CommandFields a
command [Char]
"auth"
    (ParserInfo AppCommand -> Mod CommandFields AppCommand)
-> ParserInfo AppCommand -> Mod CommandFields AppCommand
forall a b. (a -> b) -> a -> b
$ Parser AppCommand -> InfoMod AppCommand -> ParserInfo AppCommand
forall a. Parser a -> InfoMod a -> ParserInfo a
info
        (AuthOptions -> AppCommand
AppCommandAuth (AuthOptions -> AppCommand)
-> Parser AuthOptions -> Parser AppCommand
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser AuthOptions
authOptionsParser)
        ([Char] -> InfoMod AppCommand
forall a. [Char] -> InfoMod a
progDesc
          [Char]
"Authenticate using a Matrix account and get a JSON with credentials\
          \ you can use for the bot")

  startCommand  Mod CommandFields AppCommand
  startCommand :: Mod CommandFields AppCommand
startCommand
    = [Char] -> ParserInfo AppCommand -> Mod CommandFields AppCommand
forall a. [Char] -> ParserInfo a -> Mod CommandFields a
command [Char]
"start"
    (ParserInfo AppCommand -> Mod CommandFields AppCommand)
-> ParserInfo AppCommand -> Mod CommandFields AppCommand
forall a b. (a -> b) -> a -> b
$ Parser AppCommand -> InfoMod AppCommand -> ParserInfo AppCommand
forall a. Parser a -> InfoMod a -> ParserInfo a
info
        (StartOptions -> AppCommand
AppCommandStart (StartOptions -> AppCommand)
-> Parser StartOptions -> Parser AppCommand
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser StartOptions
startOptionsParser)
        ([Char] -> InfoMod AppCommand
forall a. [Char] -> InfoMod a
progDesc [Char]
"Start the bot daemon")

  sendMessageCommand  Mod CommandFields AppCommand
  sendMessageCommand :: Mod CommandFields AppCommand
sendMessageCommand
    = [Char] -> ParserInfo AppCommand -> Mod CommandFields AppCommand
forall a. [Char] -> ParserInfo a -> Mod CommandFields a
command [Char]
"send-message"
    (ParserInfo AppCommand -> Mod CommandFields AppCommand)
-> ParserInfo AppCommand -> Mod CommandFields AppCommand
forall a b. (a -> b) -> a -> b
$ Parser AppCommand -> InfoMod AppCommand -> ParserInfo AppCommand
forall a. Parser a -> InfoMod a -> ParserInfo a
info
        (SendMessageOptions -> AppCommand
AppCommandSendMessage (SendMessageOptions -> AppCommand)
-> Parser SendMessageOptions -> Parser AppCommand
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser SendMessageOptions
sendMessageOptionsParser)
        ([Char] -> InfoMod AppCommand
forall a. [Char] -> InfoMod a
progDesc [Char]
"Send text message to a room\
                  \ (will write a JSON object to stdout with transaction ID and server response)")

  editMessageCommand  Mod CommandFields AppCommand
  editMessageCommand :: Mod CommandFields AppCommand
editMessageCommand
    = [Char] -> ParserInfo AppCommand -> Mod CommandFields AppCommand
forall a. [Char] -> ParserInfo a -> Mod CommandFields a
command [Char]
"edit-message"
    (ParserInfo AppCommand -> Mod CommandFields AppCommand)
-> ParserInfo AppCommand -> Mod CommandFields AppCommand
forall a b. (a -> b) -> a -> b
$ Parser AppCommand -> InfoMod AppCommand -> ParserInfo AppCommand
forall a. Parser a -> InfoMod a -> ParserInfo a
info
        (EditMessageOptions -> AppCommand
AppCommandEditMessage (EditMessageOptions -> AppCommand)
-> Parser EditMessageOptions -> Parser AppCommand
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser EditMessageOptions
editMessageOptionsParser)
        ([Char] -> InfoMod AppCommand
forall a. [Char] -> InfoMod a
progDesc [Char]
"Edit existing text message event\
                  \ (will write a JSON object to stdout with transaction ID and server response)")


-- * Authorization

data AuthOptions = AuthOptions
  { AuthOptions -> Mxid
authOptionsMxid  Mxid
  -- ^ Where to save credentials JSON output to (can be @/dev/stdout@)
  , AuthOptions -> Either Password [Char]
authOptionsPassword  Either Password FilePath
  -- ^ Either file to read the password from (can be @/dev/stdin@) or the password as-is
  , AuthOptions -> [Char]
authOptionsOutputFile  FilePath
  , AuthOptions -> Maybe LogLevel
authOptionsLogLevel  Maybe ML.LogLevel
  }
  deriving stock (AuthOptions -> AuthOptions -> Bool
(AuthOptions -> AuthOptions -> Bool)
-> (AuthOptions -> AuthOptions -> Bool) -> Eq AuthOptions
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: AuthOptions -> AuthOptions -> Bool
== :: AuthOptions -> AuthOptions -> Bool
$c/= :: AuthOptions -> AuthOptions -> Bool
/= :: AuthOptions -> AuthOptions -> Bool
Eq, Int -> AuthOptions -> ShowS
[AuthOptions] -> ShowS
AuthOptions -> [Char]
(Int -> AuthOptions -> ShowS)
-> (AuthOptions -> [Char])
-> ([AuthOptions] -> ShowS)
-> Show AuthOptions
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> AuthOptions -> ShowS
showsPrec :: Int -> AuthOptions -> ShowS
$cshow :: AuthOptions -> [Char]
show :: AuthOptions -> [Char]
$cshowList :: [AuthOptions] -> ShowS
showList :: [AuthOptions] -> ShowS
Show)

authOptionsParser  Parser AuthOptions
authOptionsParser :: Parser AuthOptions
authOptionsParser = Parser AuthOptions
go where
  go :: Parser AuthOptions
go = Mxid
-> Either Password [Char]
-> [Char]
-> Maybe LogLevel
-> AuthOptions
AuthOptions (Mxid
 -> Either Password [Char]
 -> [Char]
 -> Maybe LogLevel
 -> AuthOptions)
-> Parser Mxid
-> Parser
     (Either Password [Char] -> [Char] -> Maybe LogLevel -> AuthOptions)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Mxid
mxid Parser
  (Either Password [Char] -> [Char] -> Maybe LogLevel -> AuthOptions)
-> Parser (Either Password [Char])
-> Parser ([Char] -> Maybe LogLevel -> AuthOptions)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser (Either Password [Char])
password Parser ([Char] -> Maybe LogLevel -> AuthOptions)
-> Parser [Char] -> Parser (Maybe LogLevel -> AuthOptions)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser [Char]
outputFile Parser (Maybe LogLevel -> AuthOptions)
-> Parser (Maybe LogLevel) -> Parser AuthOptions
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser (Maybe LogLevel)
logLevel

  mxid :: Parser Mxid
mxid = ReadM Mxid -> Mod OptionFields Mxid -> Parser Mxid
forall a. ReadM a -> Mod OptionFields a -> Parser a
option (([Char] -> Either [Char] Mxid) -> ReadM Mxid
forall a. ([Char] -> Either [Char] a) -> ReadM a
eitherReader (([Char] -> Either [Char] Mxid) -> ReadM Mxid)
-> ([Char] -> Either [Char] Mxid) -> ReadM Mxid
forall a b. (a -> b) -> a -> b
$ Parser Mxid -> Text -> Either [Char] Mxid
forall a. Parser a -> Text -> Either [Char] a
AP.parseOnly Parser Mxid
mxidParser (Text -> Either [Char] Mxid)
-> ([Char] -> Text) -> [Char] -> Either [Char] Mxid
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> Text
pack) (Mod OptionFields Mxid -> Parser Mxid)
-> Mod OptionFields Mxid -> Parser Mxid
forall a b. (a -> b) -> a -> b
$ [Mod OptionFields Mxid] -> Mod OptionFields Mxid
forall a. Monoid a => [a] -> a
mconcat
    [ [Char] -> Mod OptionFields Mxid
forall (f :: * -> *) a. HasName f => [Char] -> Mod f a
long [Char]
"mxid"
    , Char -> Mod OptionFields Mxid
forall (f :: * -> *) a. HasName f => Char -> Mod f a
short Char
'u'
    , [Char] -> Mod OptionFields Mxid
forall (f :: * -> *) a. [Char] -> Mod f a
help [Char]
"MXID (in format @username:homeserver)"
    , [Char] -> Mod OptionFields Mxid
forall (f :: * -> *) a. HasMetavar f => [Char] -> Mod f a
metavar [Char]
"MXID"
    ]

  password :: Parser (Either Password [Char])
password = (Password -> Either Password [Char])
-> Parser Password -> Parser (Either Password [Char])
forall a b. (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Password -> Either Password [Char]
forall a b. a -> Either a b
Left Parser Password
passwordValue Parser (Either Password [Char])
-> Parser (Either Password [Char])
-> Parser (Either Password [Char])
forall a. Parser a -> Parser a -> Parser a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ([Char] -> Either Password [Char])
-> Parser [Char] -> Parser (Either Password [Char])
forall a b. (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [Char] -> Either Password [Char]
forall a b. b -> Either a b
Right Parser [Char]
passwordFile

  passwordValue :: Parser Password
passwordValue = (Text -> Password) -> Parser Text -> Parser Password
forall a b. (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Text -> Password
Password (Parser Text -> Parser Password)
-> (Mod OptionFields Text -> Parser Text)
-> Mod OptionFields Text
-> Parser Password
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Mod OptionFields Text -> Parser Text
forall s. IsString s => Mod OptionFields s -> Parser s
strOption (Mod OptionFields Text -> Parser Password)
-> Mod OptionFields Text -> Parser Password
forall a b. (a -> b) -> a -> b
$ [Mod OptionFields Text] -> Mod OptionFields Text
forall a. Monoid a => [a] -> a
mconcat
    [ [Char] -> Mod OptionFields Text
forall (f :: * -> *) a. HasName f => [Char] -> Mod f a
long [Char]
"password"
    , Char -> Mod OptionFields Text
forall (f :: * -> *) a. HasName f => Char -> Mod f a
short Char
'p'
    , [Char] -> Mod OptionFields Text
forall (f :: * -> *) a. [Char] -> Mod f a
help [Char]
"Password value (--password-file is more preferable)"
    , [Char] -> Mod OptionFields Text
forall (f :: * -> *) a. HasMetavar f => [Char] -> Mod f a
metavar [Char]
"PASSWORD"
    ]

  passwordFile :: Parser [Char]
passwordFile = Mod OptionFields [Char] -> Parser [Char]
forall s. IsString s => Mod OptionFields s -> Parser s
strOption (Mod OptionFields [Char] -> Parser [Char])
-> Mod OptionFields [Char] -> Parser [Char]
forall a b. (a -> b) -> a -> b
$ [Mod OptionFields [Char]] -> Mod OptionFields [Char]
forall a. Monoid a => [a] -> a
mconcat
    [ [Char] -> Mod OptionFields [Char]
forall (f :: * -> *) a. HasName f => [Char] -> Mod f a
long [Char]
"password-file"
    , Char -> Mod OptionFields [Char]
forall (f :: * -> *) a. HasName f => Char -> Mod f a
short Char
'f'
    , [Char] -> Mod OptionFields [Char]
forall (f :: * -> *) a. [Char] -> Mod f a
help [Char]
"Path to a file containing password (e.g. /dev/stdin)"
    , [Char] -> Mod OptionFields [Char]
forall (f :: * -> *) a. HasValue f => a -> Mod f a
value [Char]
"/dev/stdin"
    , Mod OptionFields [Char]
forall a (f :: * -> *). Show a => Mod f a
showDefault
    , [Char] -> Mod OptionFields [Char]
forall (f :: * -> *) a. HasMetavar f => [Char] -> Mod f a
metavar [Char]
"FILE"
    ]

  outputFile :: Parser [Char]
outputFile = Mod OptionFields [Char] -> Parser [Char]
forall s. IsString s => Mod OptionFields s -> Parser s
strOption (Mod OptionFields [Char] -> Parser [Char])
-> Mod OptionFields [Char] -> Parser [Char]
forall a b. (a -> b) -> a -> b
$ [Mod OptionFields [Char]] -> Mod OptionFields [Char]
forall a. Monoid a => [a] -> a
mconcat
    [ [Char] -> Mod OptionFields [Char]
forall (f :: * -> *) a. HasName f => [Char] -> Mod f a
long [Char]
"output"
    , Char -> Mod OptionFields [Char]
forall (f :: * -> *) a. HasName f => Char -> Mod f a
short Char
'o'
    , [Char] -> Mod OptionFields [Char]
forall (f :: * -> *) a. [Char] -> Mod f a
help [Char]
"Where to save JSON with obtained credentials to"
    , [Char] -> Mod OptionFields [Char]
forall (f :: * -> *) a. HasMetavar f => [Char] -> Mod f a
metavar [Char]
"FILE"
    , [Char] -> Mod OptionFields [Char]
forall (f :: * -> *) a. HasValue f => a -> Mod f a
value [Char]
"/dev/stdout"
    , Mod OptionFields [Char]
forall a (f :: * -> *). Show a => Mod f a
showDefault
    ]


-- * Bot start

data StartOptions = StartOptions
  { StartOptions -> [Char]
startOptionsCredentialsFile  FilePath
  -- ^ Path to the file with credentials obtained via calling “auth” command
  , StartOptions -> [Char]
startOptionsBotConfigFile  FilePath
  -- ^ Bot configuration JSON file
  , StartOptions -> RetryLimit
startOptionsRetryLimit  RetryLimit
  -- ^ In case of Matrix API request exception how many times to retry before bot dies
  , StartOptions -> RetryDelay
startOptionsRetryDelay  RetryDelay
  -- ^ In case of Matrix API request exception how long to wait before each retry
  , StartOptions -> Maybe [Char]
startOptionsEventTokenFile  Maybe FilePath
  -- ^ Path to a JSON file that contains last event token to start listening events from (when
  --   application starts it reads from this file, when it receives new events it writes to it)
  , StartOptions -> EventsTimeout
startOptionsEventsTimeout  EventsTimeout
  , StartOptions -> Maybe LogLevel
startOptionsLogLevel  Maybe ML.LogLevel
  }
  deriving stock (StartOptions -> StartOptions -> Bool
(StartOptions -> StartOptions -> Bool)
-> (StartOptions -> StartOptions -> Bool) -> Eq StartOptions
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: StartOptions -> StartOptions -> Bool
== :: StartOptions -> StartOptions -> Bool
$c/= :: StartOptions -> StartOptions -> Bool
/= :: StartOptions -> StartOptions -> Bool
Eq, Int -> StartOptions -> ShowS
[StartOptions] -> ShowS
StartOptions -> [Char]
(Int -> StartOptions -> ShowS)
-> (StartOptions -> [Char])
-> ([StartOptions] -> ShowS)
-> Show StartOptions
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> StartOptions -> ShowS
showsPrec :: Int -> StartOptions -> ShowS
$cshow :: StartOptions -> [Char]
show :: StartOptions -> [Char]
$cshowList :: [StartOptions] -> ShowS
showList :: [StartOptions] -> ShowS
Show)

startOptionsParser  Parser StartOptions
startOptionsParser :: Parser StartOptions
startOptionsParser = Parser StartOptions
go where
  go :: Parser StartOptions
go = [Char]
-> [Char]
-> RetryLimit
-> RetryDelay
-> Maybe [Char]
-> EventsTimeout
-> Maybe LogLevel
-> StartOptions
StartOptions
    ([Char]
 -> [Char]
 -> RetryLimit
 -> RetryDelay
 -> Maybe [Char]
 -> EventsTimeout
 -> Maybe LogLevel
 -> StartOptions)
-> Parser [Char]
-> Parser
     ([Char]
      -> RetryLimit
      -> RetryDelay
      -> Maybe [Char]
      -> EventsTimeout
      -> Maybe LogLevel
      -> StartOptions)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser [Char]
credentialsFile
    Parser
  ([Char]
   -> RetryLimit
   -> RetryDelay
   -> Maybe [Char]
   -> EventsTimeout
   -> Maybe LogLevel
   -> StartOptions)
-> Parser [Char]
-> Parser
     (RetryLimit
      -> RetryDelay
      -> Maybe [Char]
      -> EventsTimeout
      -> Maybe LogLevel
      -> StartOptions)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser [Char]
botConfigFile
    Parser
  (RetryLimit
   -> RetryDelay
   -> Maybe [Char]
   -> EventsTimeout
   -> Maybe LogLevel
   -> StartOptions)
-> Parser RetryLimit
-> Parser
     (RetryDelay
      -> Maybe [Char] -> EventsTimeout -> Maybe LogLevel -> StartOptions)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser RetryLimit
retryLimit'
    Parser
  (RetryDelay
   -> Maybe [Char] -> EventsTimeout -> Maybe LogLevel -> StartOptions)
-> Parser RetryDelay
-> Parser
     (Maybe [Char] -> EventsTimeout -> Maybe LogLevel -> StartOptions)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser RetryDelay
retryDelay'
    Parser
  (Maybe [Char] -> EventsTimeout -> Maybe LogLevel -> StartOptions)
-> Parser (Maybe [Char])
-> Parser (EventsTimeout -> Maybe LogLevel -> StartOptions)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser (Maybe [Char])
eventToken
    Parser (EventsTimeout -> Maybe LogLevel -> StartOptions)
-> Parser EventsTimeout -> Parser (Maybe LogLevel -> StartOptions)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser EventsTimeout
eventsTimeout
    Parser (Maybe LogLevel -> StartOptions)
-> Parser (Maybe LogLevel) -> Parser StartOptions
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser (Maybe LogLevel)
logLevel

  botConfigFile :: Parser [Char]
botConfigFile = Mod OptionFields [Char] -> Parser [Char]
forall s. IsString s => Mod OptionFields s -> Parser s
strOption (Mod OptionFields [Char] -> Parser [Char])
-> Mod OptionFields [Char] -> Parser [Char]
forall a b. (a -> b) -> a -> b
$ [Mod OptionFields [Char]] -> Mod OptionFields [Char]
forall a. Monoid a => [a] -> a
mconcat
    [ [Char] -> Mod OptionFields [Char]
forall (f :: * -> *) a. HasName f => [Char] -> Mod f a
long [Char]
"bot-config"
    , Char -> Mod OptionFields [Char]
forall (f :: * -> *) a. HasName f => Char -> Mod f a
short Char
'c'
    , [Char] -> Mod OptionFields [Char]
forall (f :: * -> *) a. [Char] -> Mod f a
help [Char]
"Bot configuration JSON file for bot authentication"
    , [Char] -> Mod OptionFields [Char]
forall (f :: * -> *) a. HasMetavar f => [Char] -> Mod f a
metavar [Char]
"FILE"
    ]

  retryLimit' :: Parser RetryLimit
retryLimit' = (Natural -> RetryLimit) -> Parser Natural -> Parser RetryLimit
forall a b. (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Natural -> RetryLimit
RetryLimit (Parser Natural -> Parser RetryLimit)
-> (Mod OptionFields Natural -> Parser Natural)
-> Mod OptionFields Natural
-> Parser RetryLimit
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ReadM Natural -> Mod OptionFields Natural -> Parser Natural
forall a. ReadM a -> Mod OptionFields a -> Parser a
option ReadM Natural
forall a. Read a => ReadM a
auto (Mod OptionFields Natural -> Parser RetryLimit)
-> Mod OptionFields Natural -> Parser RetryLimit
forall a b. (a -> b) -> a -> b
$ [Mod OptionFields Natural] -> Mod OptionFields Natural
forall a. Monoid a => [a] -> a
mconcat
    [ [Char] -> Mod OptionFields Natural
forall (f :: * -> *) a. HasName f => [Char] -> Mod f a
long [Char]
"retry-limit"
    , [Char] -> Mod OptionFields Natural
forall (f :: * -> *) a. [Char] -> Mod f a
help [Char]
"How many times to retry failed Matrix API call before bot dies"
    , [Char] -> Mod OptionFields Natural
forall (f :: * -> *) a. HasMetavar f => [Char] -> Mod f a
metavar [Char]
"AMOUNT"
    , Natural -> Mod OptionFields Natural
forall (f :: * -> *) a. HasValue f => a -> Mod f a
value Natural
10
    , Mod OptionFields Natural
forall a (f :: * -> *). Show a => Mod f a
showDefault
    ]

  retryDelay' :: Parser RetryDelay
retryDelay' = ReadM RetryDelay
-> Mod OptionFields RetryDelay -> Parser RetryDelay
forall a. ReadM a -> Mod OptionFields a -> Parser a
option (Microseconds -> RetryDelay
RetryDelay (Microseconds -> RetryDelay)
-> ReadM Microseconds -> ReadM RetryDelay
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ReadM Microseconds
fractionalSeconds) (Mod OptionFields RetryDelay -> Parser RetryDelay)
-> Mod OptionFields RetryDelay -> Parser RetryDelay
forall a b. (a -> b) -> a -> b
$ [Mod OptionFields RetryDelay] -> Mod OptionFields RetryDelay
forall a. Monoid a => [a] -> a
mconcat
    [ [Char] -> Mod OptionFields RetryDelay
forall (f :: * -> *) a. HasName f => [Char] -> Mod f a
long [Char]
"retry-delay"
    , [Char] -> Mod OptionFields RetryDelay
forall (f :: * -> *) a. [Char] -> Mod f a
help [Char]
"How long to wait before each retry for failed Matrix API call"
    , [Char] -> Mod OptionFields RetryDelay
forall (f :: * -> *) a. HasMetavar f => [Char] -> Mod f a
metavar [Char]
"SECONDS"
    , RetryDelay -> Mod OptionFields RetryDelay
forall (f :: * -> *) a. HasValue f => a -> Mod f a
value (RetryDelay -> Mod OptionFields RetryDelay)
-> (Integer -> RetryDelay)
-> Integer
-> Mod OptionFields RetryDelay
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Microseconds -> RetryDelay
RetryDelay (Microseconds -> RetryDelay)
-> (Integer -> Microseconds) -> Integer -> RetryDelay
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Seconds -> Microseconds
secondsToMicroseconds (Seconds -> Microseconds)
-> (Integer -> Seconds) -> Integer -> Microseconds
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> Seconds
Seconds (Integer -> Mod OptionFields RetryDelay)
-> Integer -> Mod OptionFields RetryDelay
forall a b. (a -> b) -> a -> b
$ Integer
30
    , (RetryDelay -> [Char]) -> Mod OptionFields RetryDelay
forall a (f :: * -> *). (a -> [Char]) -> Mod f a
showDefaultWith RetryDelay -> [Char]
forall s. IsString s => RetryDelay -> s
printRetryDelaySeconds
    ]
    where
      fractionalSeconds  ReadM Microseconds
      fractionalSeconds :: ReadM Microseconds
fractionalSeconds = Integer -> Microseconds
Microseconds (Integer -> Microseconds)
-> (Double -> Integer) -> Double -> Microseconds
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> Integer
forall b. Integral b => Double -> b
forall a b. (RealFrac a, Integral b) => a -> b
round (Double -> Integer) -> (Double -> Double) -> Double -> Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
1_000_000) (Double -> Microseconds) -> ReadM Double -> ReadM Microseconds
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Read a => ReadM a
auto @Double

  eventToken :: Parser (Maybe [Char])
eventToken = ReadM (Maybe [Char])
-> Mod OptionFields (Maybe [Char]) -> Parser (Maybe [Char])
forall a. ReadM a -> Mod OptionFields a -> Parser a
option ([Char] -> Maybe [Char]
forall a. a -> Maybe a
Just ([Char] -> Maybe [Char]) -> ReadM [Char] -> ReadM (Maybe [Char])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ReadM [Char]
forall s. IsString s => ReadM s
str) (Mod OptionFields (Maybe [Char]) -> Parser (Maybe [Char]))
-> Mod OptionFields (Maybe [Char]) -> Parser (Maybe [Char])
forall a b. (a -> b) -> a -> b
$ [Mod OptionFields (Maybe [Char])]
-> Mod OptionFields (Maybe [Char])
forall a. Monoid a => [a] -> a
mconcat
    [ [Char] -> Mod OptionFields (Maybe [Char])
forall (f :: * -> *) a. HasName f => [Char] -> Mod f a
long [Char]
"event-token"
    , Char -> Mod OptionFields (Maybe [Char])
forall (f :: * -> *) a. HasName f => Char -> Mod f a
short Char
'e'
    , [Char] -> Mod OptionFields (Maybe [Char])
forall (f :: * -> *) a. [Char] -> Mod f a
help ([Char] -> Mod OptionFields (Maybe [Char]))
-> [Char] -> Mod OptionFields (Maybe [Char])
forall a b. (a -> b) -> a -> b
$ [[Char]] -> [Char]
unwords
        [ [Char]
"Optional JSON file to read last event token from to start listening for new events from"
        , [Char]
"and where to save last event token to"
        , [Char]
"(useful to not loose events from the time when the bot was offline)"
        ]
    , [Char] -> Mod OptionFields (Maybe [Char])
forall (f :: * -> *) a. HasMetavar f => [Char] -> Mod f a
metavar [Char]
"FILE"
    , Maybe [Char] -> Mod OptionFields (Maybe [Char])
forall (f :: * -> *) a. HasValue f => a -> Mod f a
value Maybe [Char]
forall a. Maybe a
Nothing
    ]

  eventsTimeout :: Parser EventsTimeout
eventsTimeout = ReadM EventsTimeout
-> Mod OptionFields EventsTimeout -> Parser EventsTimeout
forall a. ReadM a -> Mod OptionFields a -> Parser a
option (Seconds -> EventsTimeout
EventsTimeout (Seconds -> EventsTimeout)
-> (Integer -> Seconds) -> Integer -> EventsTimeout
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> Seconds
Seconds (Integer -> EventsTimeout) -> ReadM Integer -> ReadM EventsTimeout
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ReadM Integer
forall a. Read a => ReadM a
auto) (Mod OptionFields EventsTimeout -> Parser EventsTimeout)
-> Mod OptionFields EventsTimeout -> Parser EventsTimeout
forall a b. (a -> b) -> a -> b
$ [Mod OptionFields EventsTimeout] -> Mod OptionFields EventsTimeout
forall a. Monoid a => [a] -> a
mconcat
    [ [Char] -> Mod OptionFields EventsTimeout
forall (f :: * -> *) a. HasName f => [Char] -> Mod f a
long [Char]
"events-timeout"
    , [Char] -> Mod OptionFields EventsTimeout
forall (f :: * -> *) a. [Char] -> Mod f a
help ([Char] -> Mod OptionFields EventsTimeout)
-> [Char] -> Mod OptionFields EventsTimeout
forall a b. (a -> b) -> a -> b
$ [[Char]] -> [Char]
unwords
        [ [Char]
"Amount of seconds before waiting for next events returns early with an empty list of new"
        , [Char]
"events to go to second iteration (infinite loop of events listening)"
        ]
    , [Char] -> Mod OptionFields EventsTimeout
forall (f :: * -> *) a. HasMetavar f => [Char] -> Mod f a
metavar [Char]
"SECONDS"
    , EventsTimeout -> Mod OptionFields EventsTimeout
forall (f :: * -> *) a. HasValue f => a -> Mod f a
value (EventsTimeout -> Mod OptionFields EventsTimeout)
-> (Integer -> EventsTimeout)
-> Integer
-> Mod OptionFields EventsTimeout
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Seconds -> EventsTimeout
EventsTimeout (Seconds -> EventsTimeout)
-> (Integer -> Seconds) -> Integer -> EventsTimeout
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> Seconds
Seconds (Integer -> Mod OptionFields EventsTimeout)
-> Integer -> Mod OptionFields EventsTimeout
forall a b. (a -> b) -> a -> b
$ Integer
60
    , (EventsTimeout -> [Char]) -> Mod OptionFields EventsTimeout
forall a (f :: * -> *). (a -> [Char]) -> Mod f a
showDefaultWith ((EventsTimeout -> [Char]) -> Mod OptionFields EventsTimeout)
-> (EventsTimeout -> [Char]) -> Mod OptionFields EventsTimeout
forall a b. (a -> b) -> a -> b
$ ([Char] -> ShowS
forall a. Semigroup a => a -> a -> a
<> [Char]
" second(s)") ShowS -> (EventsTimeout -> [Char]) -> EventsTimeout -> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> [Char]
forall a. Show a => a -> [Char]
show (Integer -> [Char])
-> (EventsTimeout -> Integer) -> EventsTimeout -> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Seconds -> Integer
unSeconds (Seconds -> Integer)
-> (EventsTimeout -> Seconds) -> EventsTimeout -> Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. EventsTimeout -> Seconds
unEventsTimeout
    ]


-- * Send message command options

data SendMessageOptions = SendMessageOptions
  { SendMessageOptions -> [Char]
sendMessageOptionsCredentialsFile  FilePath
  , SendMessageOptions -> RoomId
sendMessageOptionsRoomId  RoomId
  , SendMessageOptions -> Maybe EventId
sendMessageOptionsReplyTo  Maybe EventId
  -- ^ Optionaly make the message a reply to a specified event
  , SendMessageOptions -> Either Text [Char]
sendMessageOptionsMessage  Either Text FilePath
  -- ^ Message body either as plain value or a file to read it from (e.g. /dev/stdin)
  , SendMessageOptions -> Maybe (Either Text [Char])
sendMessageOptionsHtmlMessage  Maybe (Either Text FilePath)
  -- ^ Optional HTML-formatted message body in addition to the plain text one
  , SendMessageOptions -> Maybe TransactionId
sendMessageOptionsTransactionId  Maybe TransactionId
  , SendMessageOptions -> Maybe LogLevel
sendMessageOptionsLogLevel  Maybe ML.LogLevel
  }
  deriving stock (SendMessageOptions -> SendMessageOptions -> Bool
(SendMessageOptions -> SendMessageOptions -> Bool)
-> (SendMessageOptions -> SendMessageOptions -> Bool)
-> Eq SendMessageOptions
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: SendMessageOptions -> SendMessageOptions -> Bool
== :: SendMessageOptions -> SendMessageOptions -> Bool
$c/= :: SendMessageOptions -> SendMessageOptions -> Bool
/= :: SendMessageOptions -> SendMessageOptions -> Bool
Eq, Int -> SendMessageOptions -> ShowS
[SendMessageOptions] -> ShowS
SendMessageOptions -> [Char]
(Int -> SendMessageOptions -> ShowS)
-> (SendMessageOptions -> [Char])
-> ([SendMessageOptions] -> ShowS)
-> Show SendMessageOptions
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> SendMessageOptions -> ShowS
showsPrec :: Int -> SendMessageOptions -> ShowS
$cshow :: SendMessageOptions -> [Char]
show :: SendMessageOptions -> [Char]
$cshowList :: [SendMessageOptions] -> ShowS
showList :: [SendMessageOptions] -> ShowS
Show)

sendMessageOptionsParser  Parser SendMessageOptions
sendMessageOptionsParser :: Parser SendMessageOptions
sendMessageOptionsParser = Parser SendMessageOptions
go where
  go :: Parser SendMessageOptions
go = [Char]
-> RoomId
-> Maybe EventId
-> Either Text [Char]
-> Maybe (Either Text [Char])
-> Maybe TransactionId
-> Maybe LogLevel
-> SendMessageOptions
SendMessageOptions
    ([Char]
 -> RoomId
 -> Maybe EventId
 -> Either Text [Char]
 -> Maybe (Either Text [Char])
 -> Maybe TransactionId
 -> Maybe LogLevel
 -> SendMessageOptions)
-> Parser [Char]
-> Parser
     (RoomId
      -> Maybe EventId
      -> Either Text [Char]
      -> Maybe (Either Text [Char])
      -> Maybe TransactionId
      -> Maybe LogLevel
      -> SendMessageOptions)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser [Char]
credentialsFile
    Parser
  (RoomId
   -> Maybe EventId
   -> Either Text [Char]
   -> Maybe (Either Text [Char])
   -> Maybe TransactionId
   -> Maybe LogLevel
   -> SendMessageOptions)
-> Parser RoomId
-> Parser
     (Maybe EventId
      -> Either Text [Char]
      -> Maybe (Either Text [Char])
      -> Maybe TransactionId
      -> Maybe LogLevel
      -> SendMessageOptions)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser RoomId
roomId
    Parser
  (Maybe EventId
   -> Either Text [Char]
   -> Maybe (Either Text [Char])
   -> Maybe TransactionId
   -> Maybe LogLevel
   -> SendMessageOptions)
-> Parser (Maybe EventId)
-> Parser
     (Either Text [Char]
      -> Maybe (Either Text [Char])
      -> Maybe TransactionId
      -> Maybe LogLevel
      -> SendMessageOptions)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser (Maybe EventId)
replyTo
    Parser
  (Either Text [Char]
   -> Maybe (Either Text [Char])
   -> Maybe TransactionId
   -> Maybe LogLevel
   -> SendMessageOptions)
-> Parser (Either Text [Char])
-> Parser
     (Maybe (Either Text [Char])
      -> Maybe TransactionId -> Maybe LogLevel -> SendMessageOptions)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser (Either Text [Char])
message
    Parser
  (Maybe (Either Text [Char])
   -> Maybe TransactionId -> Maybe LogLevel -> SendMessageOptions)
-> Parser (Maybe (Either Text [Char]))
-> Parser
     (Maybe TransactionId -> Maybe LogLevel -> SendMessageOptions)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser (Maybe (Either Text [Char]))
htmlMessage
    Parser
  (Maybe TransactionId -> Maybe LogLevel -> SendMessageOptions)
-> Parser (Maybe TransactionId)
-> Parser (Maybe LogLevel -> SendMessageOptions)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser (Maybe TransactionId)
transactionId
    Parser (Maybe LogLevel -> SendMessageOptions)
-> Parser (Maybe LogLevel) -> Parser SendMessageOptions
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser (Maybe LogLevel)
logLevel

  replyTo  Parser (Maybe EventId)
  replyTo :: Parser (Maybe EventId)
replyTo = (Parser (Maybe EventId)
-> Parser (Maybe EventId) -> Parser (Maybe EventId)
forall a. Parser a -> Parser a -> Parser a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Maybe EventId -> Parser (Maybe EventId)
forall a. a -> Parser a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe EventId
forall a. Maybe a
Nothing) (Parser (Maybe EventId) -> Parser (Maybe EventId))
-> Parser (Maybe EventId) -> Parser (Maybe EventId)
forall a b. (a -> b) -> a -> b
$ (Text -> Maybe EventId) -> Parser Text -> Parser (Maybe EventId)
forall a b. (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (EventId -> Maybe EventId
forall a. a -> Maybe a
Just (EventId -> Maybe EventId)
-> (Text -> EventId) -> Text -> Maybe EventId
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> EventId
EventId) (Parser Text -> Parser (Maybe EventId))
-> Parser Text -> Parser (Maybe EventId)
forall a b. (a -> b) -> a -> b
$ Mod OptionFields Text -> Parser Text
forall s. IsString s => Mod OptionFields s -> Parser s
strOption (Mod OptionFields Text -> Parser Text)
-> Mod OptionFields Text -> Parser Text
forall a b. (a -> b) -> a -> b
$ [Mod OptionFields Text] -> Mod OptionFields Text
forall a. Monoid a => [a] -> a
mconcat
    [ [Char] -> Mod OptionFields Text
forall (f :: * -> *) a. HasName f => [Char] -> Mod f a
long [Char]
"reply-to"
    , [Char] -> Mod OptionFields Text
forall (f :: * -> *) a. [Char] -> Mod f a
help [Char]
"Event ID this message is replying to"
    , [Char] -> Mod OptionFields Text
forall (f :: * -> *) a. HasMetavar f => [Char] -> Mod f a
metavar [Char]
"EVENT_ID"
    ]

  message  Parser (Either Text FilePath)
  message :: Parser (Either Text [Char])
message = (Text -> Either Text [Char])
-> Parser Text -> Parser (Either Text [Char])
forall a b. (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Text -> Either Text [Char]
forall a b. a -> Either a b
Left Parser Text
messageValue Parser (Either Text [Char])
-> Parser (Either Text [Char]) -> Parser (Either Text [Char])
forall a. Parser a -> Parser a -> Parser a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ([Char] -> Either Text [Char])
-> Parser [Char] -> Parser (Either Text [Char])
forall a b. (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [Char] -> Either Text [Char]
forall a b. b -> Either a b
Right Parser [Char]
messageFile

  htmlMessage  Parser (Maybe (Either Text FilePath))
  htmlMessage :: Parser (Maybe (Either Text [Char]))
htmlMessage =
    (Either Text [Char] -> Maybe (Either Text [Char]))
-> Parser (Either Text [Char])
-> Parser (Maybe (Either Text [Char]))
forall a b. (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Either Text [Char] -> Maybe (Either Text [Char])
forall a. a -> Maybe a
Just ((Text -> Either Text [Char])
-> Parser Text -> Parser (Either Text [Char])
forall a b. (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Text -> Either Text [Char]
forall a b. a -> Either a b
Left Parser Text
htmlMessageValue Parser (Either Text [Char])
-> Parser (Either Text [Char]) -> Parser (Either Text [Char])
forall a. Parser a -> Parser a -> Parser a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ([Char] -> Either Text [Char])
-> Parser [Char] -> Parser (Either Text [Char])
forall a b. (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [Char] -> Either Text [Char]
forall a b. b -> Either a b
Right Parser [Char]
htmlMessageFile)
    Parser (Maybe (Either Text [Char]))
-> Parser (Maybe (Either Text [Char]))
-> Parser (Maybe (Either Text [Char]))
forall a. Parser a -> Parser a -> Parser a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Maybe (Either Text [Char]) -> Parser (Maybe (Either Text [Char]))
forall a. a -> Parser a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe (Either Text [Char])
forall a. Maybe a
Nothing

  messageValue :: Parser Text
messageValue = Mod OptionFields Text -> Parser Text
forall s. IsString s => Mod OptionFields s -> Parser s
strOption (Mod OptionFields Text -> Parser Text)
-> Mod OptionFields Text -> Parser Text
forall a b. (a -> b) -> a -> b
$ [Mod OptionFields Text] -> Mod OptionFields Text
forall a. Monoid a => [a] -> a
mconcat
    [ [Char] -> Mod OptionFields Text
forall (f :: * -> *) a. HasName f => [Char] -> Mod f a
long [Char]
"message"
    , Char -> Mod OptionFields Text
forall (f :: * -> *) a. HasName f => Char -> Mod f a
short Char
'm'
    , [Char] -> Mod OptionFields Text
forall (f :: * -> *) a. [Char] -> Mod f a
help [Char]
"Text message to send to the room"
    , [Char] -> Mod OptionFields Text
forall (f :: * -> *) a. HasMetavar f => [Char] -> Mod f a
metavar [Char]
"TEXT"
    ]

  htmlMessageValue :: Parser Text
htmlMessageValue = Mod OptionFields Text -> Parser Text
forall s. IsString s => Mod OptionFields s -> Parser s
strOption (Mod OptionFields Text -> Parser Text)
-> Mod OptionFields Text -> Parser Text
forall a b. (a -> b) -> a -> b
$ [Mod OptionFields Text] -> Mod OptionFields Text
forall a. Monoid a => [a] -> a
mconcat
    [ [Char] -> Mod OptionFields Text
forall (f :: * -> *) a. HasName f => [Char] -> Mod f a
long [Char]
"html-message"
    , [Char] -> Mod OptionFields Text
forall (f :: * -> *) a. [Char] -> Mod f a
help [Char]
"HTML-formatted message to pair with plain text one"
    , [Char] -> Mod OptionFields Text
forall (f :: * -> *) a. HasMetavar f => [Char] -> Mod f a
metavar [Char]
"HTML"
    ]

  messageFile :: Parser [Char]
messageFile = Mod OptionFields [Char] -> Parser [Char]
forall s. IsString s => Mod OptionFields s -> Parser s
strOption (Mod OptionFields [Char] -> Parser [Char])
-> Mod OptionFields [Char] -> Parser [Char]
forall a b. (a -> b) -> a -> b
$ [Mod OptionFields [Char]] -> Mod OptionFields [Char]
forall a. Monoid a => [a] -> a
mconcat
    [ [Char] -> Mod OptionFields [Char]
forall (f :: * -> *) a. HasName f => [Char] -> Mod f a
long [Char]
"message-file"
    , Char -> Mod OptionFields [Char]
forall (f :: * -> *) a. HasName f => Char -> Mod f a
short Char
'f'
    , [Char] -> Mod OptionFields [Char]
forall (f :: * -> *) a. [Char] -> Mod f a
help [Char]
"Path to a file to read text message from to send it to the room (e.g. /dev/stdin)"
    , [Char] -> Mod OptionFields [Char]
forall (f :: * -> *) a. HasValue f => a -> Mod f a
value [Char]
"/dev/stdin"
    , Mod OptionFields [Char]
forall a (f :: * -> *). Show a => Mod f a
showDefault
    , [Char] -> Mod OptionFields [Char]
forall (f :: * -> *) a. HasMetavar f => [Char] -> Mod f a
metavar [Char]
"FILE"
    ]

  htmlMessageFile :: Parser [Char]
htmlMessageFile = Mod OptionFields [Char] -> Parser [Char]
forall s. IsString s => Mod OptionFields s -> Parser s
strOption (Mod OptionFields [Char] -> Parser [Char])
-> Mod OptionFields [Char] -> Parser [Char]
forall a b. (a -> b) -> a -> b
$ [Mod OptionFields [Char]] -> Mod OptionFields [Char]
forall a. Monoid a => [a] -> a
mconcat
    [ [Char] -> Mod OptionFields [Char]
forall (f :: * -> *) a. HasName f => [Char] -> Mod f a
long [Char]
"html-message-file"
    , [Char] -> Mod OptionFields [Char]
forall (f :: * -> *) a. [Char] -> Mod f a
help [Char]
"Path to a file to read HTML-formatted message from to pair with plain text one"
    , [Char] -> Mod OptionFields [Char]
forall (f :: * -> *) a. HasMetavar f => [Char] -> Mod f a
metavar [Char]
"FILE"
    ]


-- * Edit existing message command options

data EditMessageOptions = EditMessageOptions
  { EditMessageOptions -> [Char]
editMessageOptionsCredentialsFile  FilePath
  , EditMessageOptions -> RoomId
editMessageOptionsRoomId  RoomId
  , EditMessageOptions -> EventId
editMessageOptionsMessageId  EventId
  -- ^ Original message event that we are editing
  , EditMessageOptions -> Maybe EventId
editMessageOptionsReplyTo  Maybe EventId
  -- ^ Optionaly make the message a reply to a specified event
  , EditMessageOptions -> Either Text [Char]
editMessageOptionsMessage  Either Text FilePath
  -- ^ New message body either as a plain value or a file to read it from (e.g. /dev/stdin)
  , EditMessageOptions -> Maybe (Either Text [Char])
editMessageOptionsHtmlMessage  Maybe (Either Text FilePath)
  -- ^ Optional new HTML-formatted message body in addition to the plain text one
  , EditMessageOptions -> Maybe (Either Text [Char])
editMessageOptionsMessageCompat  Maybe (Either Text FilePath)
  -- ^ Old API compatibility new message body (default template is used if not specified)
  , EditMessageOptions -> Maybe (Either Text [Char])
editMessageOptionsHtmlMessageCompat  Maybe (Either Text FilePath)
  -- ^ Old API compatibility new HTML-formatted message body (default template is used if not specified)
  , EditMessageOptions -> Maybe TransactionId
editMessageOptionsTransactionId  Maybe TransactionId
  , EditMessageOptions -> Maybe LogLevel
editMessageOptionsLogLevel  Maybe ML.LogLevel
  }
  deriving stock (EditMessageOptions -> EditMessageOptions -> Bool
(EditMessageOptions -> EditMessageOptions -> Bool)
-> (EditMessageOptions -> EditMessageOptions -> Bool)
-> Eq EditMessageOptions
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: EditMessageOptions -> EditMessageOptions -> Bool
== :: EditMessageOptions -> EditMessageOptions -> Bool
$c/= :: EditMessageOptions -> EditMessageOptions -> Bool
/= :: EditMessageOptions -> EditMessageOptions -> Bool
Eq, Int -> EditMessageOptions -> ShowS
[EditMessageOptions] -> ShowS
EditMessageOptions -> [Char]
(Int -> EditMessageOptions -> ShowS)
-> (EditMessageOptions -> [Char])
-> ([EditMessageOptions] -> ShowS)
-> Show EditMessageOptions
forall a.
(Int -> a -> ShowS) -> (a -> [Char]) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> EditMessageOptions -> ShowS
showsPrec :: Int -> EditMessageOptions -> ShowS
$cshow :: EditMessageOptions -> [Char]
show :: EditMessageOptions -> [Char]
$cshowList :: [EditMessageOptions] -> ShowS
showList :: [EditMessageOptions] -> ShowS
Show)

editMessageOptionsParser  Parser EditMessageOptions
editMessageOptionsParser :: Parser EditMessageOptions
editMessageOptionsParser = Parser EditMessageOptions
go where
  go :: Parser EditMessageOptions
go = [Char]
-> RoomId
-> EventId
-> Maybe EventId
-> Either Text [Char]
-> Maybe (Either Text [Char])
-> Maybe (Either Text [Char])
-> Maybe (Either Text [Char])
-> Maybe TransactionId
-> Maybe LogLevel
-> EditMessageOptions
EditMessageOptions
    ([Char]
 -> RoomId
 -> EventId
 -> Maybe EventId
 -> Either Text [Char]
 -> Maybe (Either Text [Char])
 -> Maybe (Either Text [Char])
 -> Maybe (Either Text [Char])
 -> Maybe TransactionId
 -> Maybe LogLevel
 -> EditMessageOptions)
-> Parser [Char]
-> Parser
     (RoomId
      -> EventId
      -> Maybe EventId
      -> Either Text [Char]
      -> Maybe (Either Text [Char])
      -> Maybe (Either Text [Char])
      -> Maybe (Either Text [Char])
      -> Maybe TransactionId
      -> Maybe LogLevel
      -> EditMessageOptions)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser [Char]
credentialsFile
    Parser
  (RoomId
   -> EventId
   -> Maybe EventId
   -> Either Text [Char]
   -> Maybe (Either Text [Char])
   -> Maybe (Either Text [Char])
   -> Maybe (Either Text [Char])
   -> Maybe TransactionId
   -> Maybe LogLevel
   -> EditMessageOptions)
-> Parser RoomId
-> Parser
     (EventId
      -> Maybe EventId
      -> Either Text [Char]
      -> Maybe (Either Text [Char])
      -> Maybe (Either Text [Char])
      -> Maybe (Either Text [Char])
      -> Maybe TransactionId
      -> Maybe LogLevel
      -> EditMessageOptions)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser RoomId
roomId
    Parser
  (EventId
   -> Maybe EventId
   -> Either Text [Char]
   -> Maybe (Either Text [Char])
   -> Maybe (Either Text [Char])
   -> Maybe (Either Text [Char])
   -> Maybe TransactionId
   -> Maybe LogLevel
   -> EditMessageOptions)
-> Parser EventId
-> Parser
     (Maybe EventId
      -> Either Text [Char]
      -> Maybe (Either Text [Char])
      -> Maybe (Either Text [Char])
      -> Maybe (Either Text [Char])
      -> Maybe TransactionId
      -> Maybe LogLevel
      -> EditMessageOptions)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser EventId
messageId
    Parser
  (Maybe EventId
   -> Either Text [Char]
   -> Maybe (Either Text [Char])
   -> Maybe (Either Text [Char])
   -> Maybe (Either Text [Char])
   -> Maybe TransactionId
   -> Maybe LogLevel
   -> EditMessageOptions)
-> Parser (Maybe EventId)
-> Parser
     (Either Text [Char]
      -> Maybe (Either Text [Char])
      -> Maybe (Either Text [Char])
      -> Maybe (Either Text [Char])
      -> Maybe TransactionId
      -> Maybe LogLevel
      -> EditMessageOptions)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser (Maybe EventId)
replyTo
    Parser
  (Either Text [Char]
   -> Maybe (Either Text [Char])
   -> Maybe (Either Text [Char])
   -> Maybe (Either Text [Char])
   -> Maybe TransactionId
   -> Maybe LogLevel
   -> EditMessageOptions)
-> Parser (Either Text [Char])
-> Parser
     (Maybe (Either Text [Char])
      -> Maybe (Either Text [Char])
      -> Maybe (Either Text [Char])
      -> Maybe TransactionId
      -> Maybe LogLevel
      -> EditMessageOptions)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser (Either Text [Char])
message
    Parser
  (Maybe (Either Text [Char])
   -> Maybe (Either Text [Char])
   -> Maybe (Either Text [Char])
   -> Maybe TransactionId
   -> Maybe LogLevel
   -> EditMessageOptions)
-> Parser (Maybe (Either Text [Char]))
-> Parser
     (Maybe (Either Text [Char])
      -> Maybe (Either Text [Char])
      -> Maybe TransactionId
      -> Maybe LogLevel
      -> EditMessageOptions)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser (Maybe (Either Text [Char]))
htmlMessage
    Parser
  (Maybe (Either Text [Char])
   -> Maybe (Either Text [Char])
   -> Maybe TransactionId
   -> Maybe LogLevel
   -> EditMessageOptions)
-> Parser (Maybe (Either Text [Char]))
-> Parser
     (Maybe (Either Text [Char])
      -> Maybe TransactionId -> Maybe LogLevel -> EditMessageOptions)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser (Maybe (Either Text [Char]))
compatMessage
    Parser
  (Maybe (Either Text [Char])
   -> Maybe TransactionId -> Maybe LogLevel -> EditMessageOptions)
-> Parser (Maybe (Either Text [Char]))
-> Parser
     (Maybe TransactionId -> Maybe LogLevel -> EditMessageOptions)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser (Maybe (Either Text [Char]))
compatHtmlMessage
    Parser
  (Maybe TransactionId -> Maybe LogLevel -> EditMessageOptions)
-> Parser (Maybe TransactionId)
-> Parser (Maybe LogLevel -> EditMessageOptions)
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser (Maybe TransactionId)
transactionId
    Parser (Maybe LogLevel -> EditMessageOptions)
-> Parser (Maybe LogLevel) -> Parser EditMessageOptions
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser (Maybe LogLevel)
logLevel

  messageId  Parser EventId
  messageId :: Parser EventId
messageId = (Text -> EventId) -> Parser Text -> Parser EventId
forall a b. (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Text -> EventId
EventId (Parser Text -> Parser EventId) -> Parser Text -> Parser EventId
forall a b. (a -> b) -> a -> b
$ Mod OptionFields Text -> Parser Text
forall s. IsString s => Mod OptionFields s -> Parser s
strOption (Mod OptionFields Text -> Parser Text)
-> Mod OptionFields Text -> Parser Text
forall a b. (a -> b) -> a -> b
$ [Mod OptionFields Text] -> Mod OptionFields Text
forall a. Monoid a => [a] -> a
mconcat
    [ [Char] -> Mod OptionFields Text
forall (f :: * -> *) a. HasName f => [Char] -> Mod f a
long [Char]
"id"
    , [Char] -> Mod OptionFields Text
forall (f :: * -> *) a. [Char] -> Mod f a
help [Char]
"Event ID of the message that is about to be edited"
    , [Char] -> Mod OptionFields Text
forall (f :: * -> *) a. HasMetavar f => [Char] -> Mod f a
metavar [Char]
"EVENT_ID"
    ]

  replyTo  Parser (Maybe EventId)
  replyTo :: Parser (Maybe EventId)
replyTo = (Parser (Maybe EventId)
-> Parser (Maybe EventId) -> Parser (Maybe EventId)
forall a. Parser a -> Parser a -> Parser a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Maybe EventId -> Parser (Maybe EventId)
forall a. a -> Parser a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe EventId
forall a. Maybe a
Nothing) (Parser (Maybe EventId) -> Parser (Maybe EventId))
-> Parser (Maybe EventId) -> Parser (Maybe EventId)
forall a b. (a -> b) -> a -> b
$ (Text -> Maybe EventId) -> Parser Text -> Parser (Maybe EventId)
forall a b. (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (EventId -> Maybe EventId
forall a. a -> Maybe a
Just (EventId -> Maybe EventId)
-> (Text -> EventId) -> Text -> Maybe EventId
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> EventId
EventId) (Parser Text -> Parser (Maybe EventId))
-> Parser Text -> Parser (Maybe EventId)
forall a b. (a -> b) -> a -> b
$ Mod OptionFields Text -> Parser Text
forall s. IsString s => Mod OptionFields s -> Parser s
strOption (Mod OptionFields Text -> Parser Text)
-> Mod OptionFields Text -> Parser Text
forall a b. (a -> b) -> a -> b
$ [Mod OptionFields Text] -> Mod OptionFields Text
forall a. Monoid a => [a] -> a
mconcat
    [ [Char] -> Mod OptionFields Text
forall (f :: * -> *) a. HasName f => [Char] -> Mod f a
long [Char]
"reply-to"
    , [Char] -> Mod OptionFields Text
forall (f :: * -> *) a. [Char] -> Mod f a
help [Char]
"Event ID this message is replying to"
    , [Char] -> Mod OptionFields Text
forall (f :: * -> *) a. HasMetavar f => [Char] -> Mod f a
metavar [Char]
"EVENT_ID"
    ]

  message  Parser (Either Text FilePath)
  message :: Parser (Either Text [Char])
message = (Text -> Either Text [Char])
-> Parser Text -> Parser (Either Text [Char])
forall a b. (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Text -> Either Text [Char]
forall a b. a -> Either a b
Left Parser Text
messageValue Parser (Either Text [Char])
-> Parser (Either Text [Char]) -> Parser (Either Text [Char])
forall a. Parser a -> Parser a -> Parser a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ([Char] -> Either Text [Char])
-> Parser [Char] -> Parser (Either Text [Char])
forall a b. (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [Char] -> Either Text [Char]
forall a b. b -> Either a b
Right Parser [Char]
messageFile

  htmlMessage  Parser (Maybe (Either Text FilePath))
  htmlMessage :: Parser (Maybe (Either Text [Char]))
htmlMessage =
    (Either Text [Char] -> Maybe (Either Text [Char]))
-> Parser (Either Text [Char])
-> Parser (Maybe (Either Text [Char]))
forall a b. (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Either Text [Char] -> Maybe (Either Text [Char])
forall a. a -> Maybe a
Just ((Text -> Either Text [Char])
-> Parser Text -> Parser (Either Text [Char])
forall a b. (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Text -> Either Text [Char]
forall a b. a -> Either a b
Left Parser Text
htmlMessageValue Parser (Either Text [Char])
-> Parser (Either Text [Char]) -> Parser (Either Text [Char])
forall a. Parser a -> Parser a -> Parser a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ([Char] -> Either Text [Char])
-> Parser [Char] -> Parser (Either Text [Char])
forall a b. (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [Char] -> Either Text [Char]
forall a b. b -> Either a b
Right Parser [Char]
htmlMessageFile)
    Parser (Maybe (Either Text [Char]))
-> Parser (Maybe (Either Text [Char]))
-> Parser (Maybe (Either Text [Char]))
forall a. Parser a -> Parser a -> Parser a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Maybe (Either Text [Char]) -> Parser (Maybe (Either Text [Char]))
forall a. a -> Parser a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe (Either Text [Char])
forall a. Maybe a
Nothing

  messageValue :: Parser Text
messageValue = Mod OptionFields Text -> Parser Text
forall s. IsString s => Mod OptionFields s -> Parser s
strOption (Mod OptionFields Text -> Parser Text)
-> Mod OptionFields Text -> Parser Text
forall a b. (a -> b) -> a -> b
$ [Mod OptionFields Text] -> Mod OptionFields Text
forall a. Monoid a => [a] -> a
mconcat
    [ [Char] -> Mod OptionFields Text
forall (f :: * -> *) a. HasName f => [Char] -> Mod f a
long [Char]
"message"
    , Char -> Mod OptionFields Text
forall (f :: * -> *) a. HasName f => Char -> Mod f a
short Char
'm'
    , [Char] -> Mod OptionFields Text
forall (f :: * -> *) a. [Char] -> Mod f a
help [Char]
"New message plain text body"
    , [Char] -> Mod OptionFields Text
forall (f :: * -> *) a. HasMetavar f => [Char] -> Mod f a
metavar [Char]
"TEXT"
    ]

  htmlMessageValue :: Parser Text
htmlMessageValue = Mod OptionFields Text -> Parser Text
forall s. IsString s => Mod OptionFields s -> Parser s
strOption (Mod OptionFields Text -> Parser Text)
-> Mod OptionFields Text -> Parser Text
forall a b. (a -> b) -> a -> b
$ [Mod OptionFields Text] -> Mod OptionFields Text
forall a. Monoid a => [a] -> a
mconcat
    [ [Char] -> Mod OptionFields Text
forall (f :: * -> *) a. HasName f => [Char] -> Mod f a
long [Char]
"html-message"
    , [Char] -> Mod OptionFields Text
forall (f :: * -> *) a. [Char] -> Mod f a
help [Char]
"New message HTML-formatted body to pair with plain text one"
    , [Char] -> Mod OptionFields Text
forall (f :: * -> *) a. HasMetavar f => [Char] -> Mod f a
metavar [Char]
"HTML"
    ]

  messageFile :: Parser [Char]
messageFile = Mod OptionFields [Char] -> Parser [Char]
forall s. IsString s => Mod OptionFields s -> Parser s
strOption (Mod OptionFields [Char] -> Parser [Char])
-> Mod OptionFields [Char] -> Parser [Char]
forall a b. (a -> b) -> a -> b
$ [Mod OptionFields [Char]] -> Mod OptionFields [Char]
forall a. Monoid a => [a] -> a
mconcat
    [ [Char] -> Mod OptionFields [Char]
forall (f :: * -> *) a. HasName f => [Char] -> Mod f a
long [Char]
"message-file"
    , Char -> Mod OptionFields [Char]
forall (f :: * -> *) a. HasName f => Char -> Mod f a
short Char
'f'
    , [Char] -> Mod OptionFields [Char]
forall (f :: * -> *) a. [Char] -> Mod f a
help [Char]
"Path to a file to read new text message body from to send it to the room (e.g. /dev/stdin)"
    , [Char] -> Mod OptionFields [Char]
forall (f :: * -> *) a. HasValue f => a -> Mod f a
value [Char]
"/dev/stdin"
    , Mod OptionFields [Char]
forall a (f :: * -> *). Show a => Mod f a
showDefault
    , [Char] -> Mod OptionFields [Char]
forall (f :: * -> *) a. HasMetavar f => [Char] -> Mod f a
metavar [Char]
"FILE"
    ]

  htmlMessageFile :: Parser [Char]
htmlMessageFile = Mod OptionFields [Char] -> Parser [Char]
forall s. IsString s => Mod OptionFields s -> Parser s
strOption (Mod OptionFields [Char] -> Parser [Char])
-> Mod OptionFields [Char] -> Parser [Char]
forall a b. (a -> b) -> a -> b
$ [Mod OptionFields [Char]] -> Mod OptionFields [Char]
forall a. Monoid a => [a] -> a
mconcat
    [ [Char] -> Mod OptionFields [Char]
forall (f :: * -> *) a. HasName f => [Char] -> Mod f a
long [Char]
"html-message-file"
    , [Char] -> Mod OptionFields [Char]
forall (f :: * -> *) a. [Char] -> Mod f a
help [Char]
"Path to a file to read new HTML-formatted message body from to pair with plain text one"
    , [Char] -> Mod OptionFields [Char]
forall (f :: * -> *) a. HasMetavar f => [Char] -> Mod f a
metavar [Char]
"FILE"
    ]

  compatMessage  Parser (Maybe (Either Text FilePath))
  compatMessage :: Parser (Maybe (Either Text [Char]))
compatMessage =
    (Either Text [Char] -> Maybe (Either Text [Char]))
-> Parser (Either Text [Char])
-> Parser (Maybe (Either Text [Char]))
forall a b. (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Either Text [Char] -> Maybe (Either Text [Char])
forall a. a -> Maybe a
Just ((Text -> Either Text [Char])
-> Parser Text -> Parser (Either Text [Char])
forall a b. (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Text -> Either Text [Char]
forall a b. a -> Either a b
Left Parser Text
compatMessageValue Parser (Either Text [Char])
-> Parser (Either Text [Char]) -> Parser (Either Text [Char])
forall a. Parser a -> Parser a -> Parser a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ([Char] -> Either Text [Char])
-> Parser [Char] -> Parser (Either Text [Char])
forall a b. (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [Char] -> Either Text [Char]
forall a b. b -> Either a b
Right Parser [Char]
compatMessageFile)
    Parser (Maybe (Either Text [Char]))
-> Parser (Maybe (Either Text [Char]))
-> Parser (Maybe (Either Text [Char]))
forall a. Parser a -> Parser a -> Parser a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Maybe (Either Text [Char]) -> Parser (Maybe (Either Text [Char]))
forall a. a -> Parser a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe (Either Text [Char])
forall a. Maybe a
Nothing

  compatHtmlMessage  Parser (Maybe (Either Text FilePath))
  compatHtmlMessage :: Parser (Maybe (Either Text [Char]))
compatHtmlMessage =
    (Either Text [Char] -> Maybe (Either Text [Char]))
-> Parser (Either Text [Char])
-> Parser (Maybe (Either Text [Char]))
forall a b. (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Either Text [Char] -> Maybe (Either Text [Char])
forall a. a -> Maybe a
Just ((Text -> Either Text [Char])
-> Parser Text -> Parser (Either Text [Char])
forall a b. (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Text -> Either Text [Char]
forall a b. a -> Either a b
Left Parser Text
compatHtmlMessageValue Parser (Either Text [Char])
-> Parser (Either Text [Char]) -> Parser (Either Text [Char])
forall a. Parser a -> Parser a -> Parser a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ([Char] -> Either Text [Char])
-> Parser [Char] -> Parser (Either Text [Char])
forall a b. (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [Char] -> Either Text [Char]
forall a b. b -> Either a b
Right Parser [Char]
compatHtmlMessageFile)
    Parser (Maybe (Either Text [Char]))
-> Parser (Maybe (Either Text [Char]))
-> Parser (Maybe (Either Text [Char]))
forall a. Parser a -> Parser a -> Parser a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Maybe (Either Text [Char]) -> Parser (Maybe (Either Text [Char]))
forall a. a -> Parser a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe (Either Text [Char])
forall a. Maybe a
Nothing

  compatMessageValue :: Parser Text
compatMessageValue = Mod OptionFields Text -> Parser Text
forall s. IsString s => Mod OptionFields s -> Parser s
strOption (Mod OptionFields Text -> Parser Text)
-> Mod OptionFields Text -> Parser Text
forall a b. (a -> b) -> a -> b
$ [Mod OptionFields Text] -> Mod OptionFields Text
forall a. Monoid a => [a] -> a
mconcat
    [ [Char] -> Mod OptionFields Text
forall (f :: * -> *) a. HasName f => [Char] -> Mod f a
long [Char]
"compat-message"
    , [Char] -> Mod OptionFields Text
forall (f :: * -> *) a. [Char] -> Mod f a
help [Char]
"Old API compatible new message plain text body (when message edits are not supported), “EDIT:” prefix template is used when not specified"
    , [Char] -> Mod OptionFields Text
forall (f :: * -> *) a. HasMetavar f => [Char] -> Mod f a
metavar [Char]
"TEXT"
    ]

  compatHtmlMessageValue :: Parser Text
compatHtmlMessageValue = Mod OptionFields Text -> Parser Text
forall s. IsString s => Mod OptionFields s -> Parser s
strOption (Mod OptionFields Text -> Parser Text)
-> Mod OptionFields Text -> Parser Text
forall a b. (a -> b) -> a -> b
$ [Mod OptionFields Text] -> Mod OptionFields Text
forall a. Monoid a => [a] -> a
mconcat
    [ [Char] -> Mod OptionFields Text
forall (f :: * -> *) a. HasName f => [Char] -> Mod f a
long [Char]
"compat-html-message"
    , [Char] -> Mod OptionFields Text
forall (f :: * -> *) a. [Char] -> Mod f a
help [Char]
"Old API compatible new message HTML-formatted body to pair with plain text one (when message edits are not supported), “<b>EDIT:</b>” prefix template is used when not specified"
    , [Char] -> Mod OptionFields Text
forall (f :: * -> *) a. HasMetavar f => [Char] -> Mod f a
metavar [Char]
"HTML"
    ]

  compatMessageFile :: Parser [Char]
compatMessageFile = Mod OptionFields [Char] -> Parser [Char]
forall s. IsString s => Mod OptionFields s -> Parser s
strOption (Mod OptionFields [Char] -> Parser [Char])
-> Mod OptionFields [Char] -> Parser [Char]
forall a b. (a -> b) -> a -> b
$ [Mod OptionFields [Char]] -> Mod OptionFields [Char]
forall a. Monoid a => [a] -> a
mconcat
    [ [Char] -> Mod OptionFields [Char]
forall (f :: * -> *) a. HasName f => [Char] -> Mod f a
long [Char]
"compat-message-file"
    , [Char] -> Mod OptionFields [Char]
forall (f :: * -> *) a. [Char] -> Mod f a
help [Char]
"Path to a file to read new text message body from to send it to the room (e.g. /dev/stdin)"
    , [Char] -> Mod OptionFields [Char]
forall (f :: * -> *) a. HasMetavar f => [Char] -> Mod f a
metavar [Char]
"FILE"
    ]

  compatHtmlMessageFile :: Parser [Char]
compatHtmlMessageFile = Mod OptionFields [Char] -> Parser [Char]
forall s. IsString s => Mod OptionFields s -> Parser s
strOption (Mod OptionFields [Char] -> Parser [Char])
-> Mod OptionFields [Char] -> Parser [Char]
forall a b. (a -> b) -> a -> b
$ [Mod OptionFields [Char]] -> Mod OptionFields [Char]
forall a. Monoid a => [a] -> a
mconcat
    [ [Char] -> Mod OptionFields [Char]
forall (f :: * -> *) a. HasName f => [Char] -> Mod f a
long [Char]
"compat-html-message-file"
    , [Char] -> Mod OptionFields [Char]
forall (f :: * -> *) a. [Char] -> Mod f a
help [Char]
"Path to a file to read new HTML-formatted message body from to pair with plain text one"
    , [Char] -> Mod OptionFields [Char]
forall (f :: * -> *) a. HasMetavar f => [Char] -> Mod f a
metavar [Char]
"FILE"
    ]


-- * Re-usable parsers

credentialsFile  Parser FilePath
credentialsFile :: Parser [Char]
credentialsFile = Mod OptionFields [Char] -> Parser [Char]
forall s. IsString s => Mod OptionFields s -> Parser s
strOption (Mod OptionFields [Char] -> Parser [Char])
-> Mod OptionFields [Char] -> Parser [Char]
forall a b. (a -> b) -> a -> b
$ [Mod OptionFields [Char]] -> Mod OptionFields [Char]
forall a. Monoid a => [a] -> a
mconcat
  [ [Char] -> Mod OptionFields [Char]
forall (f :: * -> *) a. HasName f => [Char] -> Mod f a
long [Char]
"credentials"
  , Char -> Mod OptionFields [Char]
forall (f :: * -> *) a. HasName f => Char -> Mod f a
short Char
'a'
  , [Char] -> Mod OptionFields [Char]
forall (f :: * -> *) a. [Char] -> Mod f a
help [Char]
"Credentials JSON file for authentication (call “auth” command to get one)"
  , [Char] -> Mod OptionFields [Char]
forall (f :: * -> *) a. HasMetavar f => [Char] -> Mod f a
metavar [Char]
"FILE"
  ]


roomId  Parser RoomId
roomId :: Parser RoomId
roomId = ReadM RoomId -> Mod OptionFields RoomId -> Parser RoomId
forall a. ReadM a -> Mod OptionFields a -> Parser a
option (([Char] -> Either [Char] RoomId) -> ReadM RoomId
forall a. ([Char] -> Either [Char] a) -> ReadM a
eitherReader (([Char] -> Either [Char] RoomId) -> ReadM RoomId)
-> ([Char] -> Either [Char] RoomId) -> ReadM RoomId
forall a b. (a -> b) -> a -> b
$ Parser RoomId -> Text -> Either [Char] RoomId
forall a. Parser a -> Text -> Either [Char] a
AP.parseOnly Parser RoomId
roomIdParser (Text -> Either [Char] RoomId)
-> ([Char] -> Text) -> [Char] -> Either [Char] RoomId
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> Text
pack) (Mod OptionFields RoomId -> Parser RoomId)
-> Mod OptionFields RoomId -> Parser RoomId
forall a b. (a -> b) -> a -> b
$ [Mod OptionFields RoomId] -> Mod OptionFields RoomId
forall a. Monoid a => [a] -> a
mconcat
  [ [Char] -> Mod OptionFields RoomId
forall (f :: * -> *) a. HasName f => [Char] -> Mod f a
long [Char]
"room-id"
  , Char -> Mod OptionFields RoomId
forall (f :: * -> *) a. HasName f => Char -> Mod f a
short Char
'r'
  , [Char] -> Mod OptionFields RoomId
forall (f :: * -> *) a. [Char] -> Mod f a
help [Char]
"Room identifier (e.g. !ffffffffffffffffff:matrix.org) where to send text message to"
  , [Char] -> Mod OptionFields RoomId
forall (f :: * -> *) a. HasMetavar f => [Char] -> Mod f a
metavar [Char]
"ROOM_ID"
  ]


transactionId  Parser (Maybe TransactionId)
transactionId :: Parser (Maybe TransactionId)
transactionId = ReadM (Maybe TransactionId)
-> Mod OptionFields (Maybe TransactionId)
-> Parser (Maybe TransactionId)
forall a. ReadM a -> Mod OptionFields a -> Parser a
option (TransactionId -> Maybe TransactionId
forall a. a -> Maybe a
Just (TransactionId -> Maybe TransactionId)
-> (UUID -> TransactionId) -> UUID -> Maybe TransactionId
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UUID -> TransactionId
TransactionId (UUID -> Maybe TransactionId)
-> ReadM UUID -> ReadM (Maybe TransactionId)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ([Char] -> Maybe UUID) -> ReadM UUID
forall a. ([Char] -> Maybe a) -> ReadM a
maybeReader [Char] -> Maybe UUID
fromString) (Mod OptionFields (Maybe TransactionId)
 -> Parser (Maybe TransactionId))
-> Mod OptionFields (Maybe TransactionId)
-> Parser (Maybe TransactionId)
forall a b. (a -> b) -> a -> b
$ [Mod OptionFields (Maybe TransactionId)]
-> Mod OptionFields (Maybe TransactionId)
forall a. Monoid a => [a] -> a
mconcat
  [ [Char] -> Mod OptionFields (Maybe TransactionId)
forall (f :: * -> *) a. HasName f => [Char] -> Mod f a
long [Char]
"transaction-id"
  , Char -> Mod OptionFields (Maybe TransactionId)
forall (f :: * -> *) a. HasName f => Char -> Mod f a
short Char
't'
  , [Char] -> Mod OptionFields (Maybe TransactionId)
forall (f :: * -> *) a. [Char] -> Mod f a
help ([Char] -> Mod OptionFields (Maybe TransactionId))
-> [Char] -> Mod OptionFields (Maybe TransactionId)
forall a b. (a -> b) -> a -> b
$ [[Char]] -> [Char]
unwords
      [ [Char]
"Transaction ID (any random UUID) for atomicity of the request"
      , [Char]
"(if not provided new random one will be generated)"
      ]
  , [Char] -> Mod OptionFields (Maybe TransactionId)
forall (f :: * -> *) a. HasMetavar f => [Char] -> Mod f a
metavar [Char]
"UUID"
  , Maybe TransactionId -> Mod OptionFields (Maybe TransactionId)
forall (f :: * -> *) a. HasValue f => a -> Mod f a
value Maybe TransactionId
forall a. Maybe a
Nothing
  ]


-- @Nothing@ means the log is silenced
logLevel  Parser (Maybe ML.LogLevel)
logLevel :: Parser (Maybe LogLevel)
logLevel =
  ReadM (Maybe LogLevel)
-> Mod OptionFields (Maybe LogLevel) -> Parser (Maybe LogLevel)
forall a. ReadM a -> Mod OptionFields a -> Parser a
option (([Char] -> Maybe (Maybe LogLevel)) -> ReadM (Maybe LogLevel)
forall a. ([Char] -> Maybe a) -> ReadM a
maybeReader [Char] -> Maybe (Maybe LogLevel)
parseLevel) (Mod OptionFields (Maybe LogLevel) -> Parser (Maybe LogLevel))
-> Mod OptionFields (Maybe LogLevel) -> Parser (Maybe LogLevel)
forall a b. (a -> b) -> a -> b
$ [Mod OptionFields (Maybe LogLevel)]
-> Mod OptionFields (Maybe LogLevel)
forall a. Monoid a => [a] -> a
mconcat
    [ [Char] -> Mod OptionFields (Maybe LogLevel)
forall (f :: * -> *) a. HasName f => [Char] -> Mod f a
long [Char]
"log-level"
    , Char -> Mod OptionFields (Maybe LogLevel)
forall (f :: * -> *) a. HasName f => Char -> Mod f a
short Char
'l'
    , [Char] -> Mod OptionFields (Maybe LogLevel)
forall (f :: * -> *) a. HasMetavar f => [Char] -> Mod f a
metavar [Char]
"LEVEL"
    , Maybe LogLevel -> Mod OptionFields (Maybe LogLevel)
forall (f :: * -> *) a. HasValue f => a -> Mod f a
value (LogLevel -> Maybe LogLevel
forall a. a -> Maybe a
Just LogLevel
ML.LevelDebug) -- Default is the noisiest
    , (Maybe LogLevel -> [Char]) -> Mod OptionFields (Maybe LogLevel)
forall a (f :: * -> *). (a -> [Char]) -> Mod f a
showDefaultWith (ShowS
forall a. Show a => a -> [Char]
show ShowS -> (Maybe LogLevel -> [Char]) -> Maybe LogLevel -> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe LogLevel -> [Char]
printLevel)
    , [Char] -> Mod OptionFields (Maybe LogLevel)
forall (f :: * -> *) a. [Char] -> Mod f a
help ([Char] -> Mod OptionFields (Maybe LogLevel))
-> [Char] -> Mod OptionFields (Maybe LogLevel)
forall a b. (a -> b) -> a -> b
$ [[Char]] -> [Char]
unwords
        [ [Char]
"How noisy the log is"
        , [Char]
"(any message that is less than specified log level is silenced)."
        , [Char]
"Available LEVEL options (“off” completely silences the log):"
        , [Char] -> [[Char]] -> [Char]
forall a. [a] -> [[a]] -> [a]
intercalate [Char]
", " ([[Char]] -> [Char])
-> ([Maybe LogLevel] -> [[Char]]) -> [Maybe LogLevel] -> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Maybe LogLevel -> [Char]) -> [Maybe LogLevel] -> [[Char]]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (ShowS
forall a. Show a => a -> [Char]
show ShowS -> (Maybe LogLevel -> [Char]) -> Maybe LogLevel -> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe LogLevel -> [Char]
printLevel) ([Maybe LogLevel] -> [Char]) -> [Maybe LogLevel] -> [Char]
forall a b. (a -> b) -> a -> b
$ (LogLevel -> Maybe LogLevel) -> [LogLevel] -> [Maybe LogLevel]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap LogLevel -> Maybe LogLevel
forall a. a -> Maybe a
Just [LogLevel]
allLevels [Maybe LogLevel] -> [Maybe LogLevel] -> [Maybe LogLevel]
forall a. Semigroup a => a -> a -> a
<> [Maybe LogLevel
forall a. Maybe a
Nothing]
        ]
    ]
  where
    allLevels  [ML.LogLevel]
    allLevels :: [LogLevel]
allLevels = [LogLevel
ML.LevelDebug, LogLevel
ML.LevelInfo, LogLevel
ML.LevelWarn, LogLevel
ML.LevelError]

    parseLevel  String  Maybe (Maybe ML.LogLevel)
    parseLevel :: [Char] -> Maybe (Maybe LogLevel)
parseLevel [Char]
level =
      if [Char]
level [Char] -> [Char] -> Bool
forall a. Eq a => a -> a -> Bool
== Maybe LogLevel -> [Char]
printLevel Maybe LogLevel
forall a. Maybe a
Nothing
        then Maybe LogLevel -> Maybe (Maybe LogLevel)
forall a. a -> Maybe a
Just Maybe LogLevel
forall a. Maybe a
Nothing
        else LogLevel -> Maybe LogLevel
forall a. a -> Maybe a
Just (LogLevel -> Maybe LogLevel)
-> Maybe LogLevel -> Maybe (Maybe LogLevel)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (LogLevel -> Bool) -> [LogLevel] -> Maybe LogLevel
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
find (([Char]
level [Char] -> [Char] -> Bool
forall a. Eq a => a -> a -> Bool
==) ([Char] -> Bool) -> (LogLevel -> [Char]) -> LogLevel -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe LogLevel -> [Char]
printLevel (Maybe LogLevel -> [Char])
-> (LogLevel -> Maybe LogLevel) -> LogLevel -> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LogLevel -> Maybe LogLevel
forall a. a -> Maybe a
Just) [LogLevel]
allLevels

    printLevel  Maybe ML.LogLevel  String
    printLevel :: Maybe LogLevel -> [Char]
printLevel = \case
      Maybe LogLevel
Nothing  [Char]
"off"
      Just LogLevel
ML.LevelDebug  [Char]
"debug"
      Just LogLevel
ML.LevelInfo  [Char]
"info"
      Just LogLevel
ML.LevelWarn  [Char]
"warn"
      Just LogLevel
ML.LevelError  [Char]
"error"
      Just (ML.LevelOther Text
level)  ShowS
forall a. HasCallStack => [Char] -> a
error ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$ [Char]
"Unexpected “other” log level: " [Char] -> ShowS
forall a. Semigroup a => a -> a -> a
<> Text -> [Char]
forall a. Show a => a -> [Char]
show Text
level


-- * Parsing command-line arguments

parseAppCommand  MonadIO m  m AppCommand
parseAppCommand :: forall (m :: * -> *). MonadIO m => m AppCommand
parseAppCommand = IO AppCommand -> m AppCommand
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO AppCommand -> m AppCommand) -> IO AppCommand -> m AppCommand
forall a b. (a -> b) -> a -> b
$ ParserInfo AppCommand -> IO AppCommand
forall a. ParserInfo a -> IO a
execParser ParserInfo AppCommand
appCommandParserInfo