{-# LANGUAGE CPP #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE StrictData #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeApplications #-}
{-# OPTIONS_GHC -fno-warn-implicit-lift #-}

module Simplex.Chat.Controller where

import Control.Concurrent (ThreadId)
import Control.Concurrent.Async (Async)
import Control.Exception (Exception)
import qualified Control.Exception as E
import Control.Monad.Except
import Control.Monad.IO.Unlift
import Control.Monad.Reader
import Crypto.Random (ChaChaDRG)
import Data.Aeson (FromJSON (..), ToJSON (..), (.:), (.:?))
import qualified Data.Aeson as J
import qualified Data.Aeson.TH as JQ
import qualified Data.Aeson.Types as JT
import qualified Data.Attoparsec.ByteString.Char8 as A
import Data.Bifunctor (first)
import Data.ByteArray (ScrubbedBytes)
import qualified Data.ByteArray as BA
import Data.ByteString.Char8 (ByteString)
import qualified Data.ByteString.Char8 as B
import Data.Char (ord)
import Data.Int (Int64)
import Data.List.NonEmpty (NonEmpty)
import Data.Map.Strict (Map)
import qualified Data.Map.Strict as M
import Data.Maybe (fromMaybe)
import Data.String
import Data.Text (Text)
import Data.Text.Encoding (decodeLatin1)
import Data.Time (NominalDiffTime, UTCTime)
import Data.Time.Clock.System (SystemTime (..), systemToUTCTime)
import Data.Version (showVersion)
import Data.Word (Word16)
import Language.Haskell.TH (Exp, Q, runIO)
import Network.Socket (HostName)
import Numeric.Natural
import qualified Paths_simplex_chat as SC
import Simplex.Chat.AppSettings
import Simplex.Chat.Call
import Simplex.Chat.Delivery
import Simplex.Chat.Messages
import Simplex.Chat.Messages.CIContent
import Simplex.Chat.Operators
import Simplex.Chat.Protocol
import Simplex.Chat.Remote.AppVersion
import Simplex.Chat.Remote.Types
import Simplex.Chat.Stats (PresentedServersSummary)
import Simplex.Chat.Store (AddressSettings, ChatLockEntity, GroupLinkInfo, StoreError (..), UserContactLink, UserMsgReceiptSettings)
import Simplex.Chat.Types
import Simplex.Chat.Types.Preferences
import Simplex.Chat.Types.Shared
import Simplex.Chat.Types.UITheme
import Simplex.Chat.Util (liftIOEither)
import Simplex.FileTransfer.Description (FileDescriptionURI)
import Simplex.Messaging.Agent (AgentClient, DatabaseDiff, SubscriptionsInfo)
import Simplex.Messaging.Agent.Client (AgentLocks, AgentQueuesInfo (..), AgentWorkersDetails (..), AgentWorkersSummary (..), ProtocolTestFailure, SMPServerSubs, ServerQueueInfo, UserNetworkInfo)
import Simplex.Messaging.Agent.Env.SQLite (AgentConfig, NetworkConfig, ServerCfg, Worker)
import Simplex.Messaging.Agent.Lock
import Simplex.Messaging.Agent.Protocol
import Simplex.Messaging.Agent.Store.Common (DBStore, withTransaction, withTransactionPriority)
import Simplex.Messaging.Agent.Store.Shared (MigrationConfirmation, UpMigration)
import qualified Simplex.Messaging.Agent.Store.DB as DB
import Simplex.Messaging.Client (HostMode (..), SMPProxyFallback (..), SMPProxyMode (..), SMPWebPortServers (..), SocksMode (..))
import qualified Simplex.Messaging.Crypto as C
import Simplex.Messaging.Crypto.File (CryptoFile (..))
import qualified Simplex.Messaging.Crypto.File as CF
import Simplex.Messaging.Crypto.Ratchet (PQEncryption)
import Simplex.Messaging.Encoding.String
import Simplex.Messaging.Notifications.Protocol (DeviceToken (..), NtfTknStatus)
import Simplex.Messaging.Parsers (defaultJSON, dropPrefix, enumJSON, parseAll, parseString, sumTypeJSON)
import Simplex.Messaging.Protocol (AProtoServerWithAuth, AProtocolType (..), MsgId, NMsgMeta (..), NtfServer, ProtocolType (..), QueueId, SMPMsgMeta (..), SubscriptionMode (..), XFTPServer)
import Simplex.Messaging.TMap (TMap)
import Simplex.Messaging.Transport (TLS, TransportPeer (..), simplexMQVersion)
import Simplex.Messaging.Transport.Client (SocksProxyWithAuth, TransportHost)
import Simplex.Messaging.Util (AnyError (..), catchAllErrors, (<$$>))
import Simplex.RemoteControl.Client
import Simplex.RemoteControl.Invitation (RCSignedInvitation, RCVerifiedInvitation)
import Simplex.RemoteControl.Types
import System.IO (Handle)
import System.Mem.Weak (Weak)
import UnliftIO.STM
#if !defined(dbPostgres)
import Database.SQLite.Simple (SQLError)
import qualified Database.SQLite.Simple as SQL
import Simplex.Messaging.Agent.Store.SQLite.DB (SlowQueryStats (..))
#endif

versionNumber :: String
versionNumber :: [Char]
versionNumber = Version -> [Char]
showVersion Version
SC.version

versionString :: String -> String
versionString :: [Char] -> [Char]
versionString [Char]
ver = [Char]
"SimpleX Chat v" [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> [Char]
ver

simplexmqCommitQ :: Q Exp
simplexmqCommitQ :: Q Exp
simplexmqCommitQ = do
  [Char]
s <- ([Char] -> [Char])
-> (MsgId -> [Char]) -> Either [Char] MsgId -> [Char]
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either ([Char] -> [Char] -> [Char]
forall a b. a -> b -> a
const [Char]
"") MsgId -> [Char]
B.unpack (Either [Char] MsgId -> [Char])
-> (MsgId -> Either [Char] MsgId) -> MsgId -> [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Parser MsgId MsgId -> MsgId -> Either [Char] MsgId
forall a. Parser a -> MsgId -> Either [Char] a
A.parseOnly Parser MsgId MsgId
commitHashP (MsgId -> [Char]) -> Q MsgId -> Q [Char]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IO MsgId -> Q MsgId
forall a. IO a -> Q a
runIO ([Char] -> IO MsgId
B.readFile [Char]
"./cabal.project")
  [|fromString s|]
  where
    commitHashP :: A.Parser ByteString
    commitHashP :: Parser MsgId MsgId
commitHashP =
      Parser MsgId Char -> Parser MsgId MsgId -> Parser MsgId [Char]
forall (m :: * -> *) a b. MonadPlus m => m a -> m b -> m [a]
A.manyTill' Parser MsgId Char
A.anyChar Parser MsgId MsgId
"location: https://github.com/simplex-chat/simplexmq.git"
        Parser MsgId [Char] -> Parser MsgId MsgId -> Parser MsgId MsgId
forall a b. Parser MsgId a -> Parser MsgId b -> Parser MsgId b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (Char -> Bool) -> Parser MsgId MsgId
A.takeWhile (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
' ')
        Parser MsgId MsgId -> Parser MsgId () -> Parser MsgId ()
forall a b. Parser MsgId a -> Parser MsgId b -> Parser MsgId b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser MsgId ()
A.endOfLine
        Parser MsgId () -> Parser MsgId MsgId -> Parser MsgId MsgId
forall a b. Parser MsgId a -> Parser MsgId b -> Parser MsgId b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (Char -> Bool) -> Parser MsgId MsgId
A.takeWhile (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
' ')
        Parser MsgId MsgId -> Parser MsgId MsgId -> Parser MsgId MsgId
forall a b. Parser MsgId a -> Parser MsgId b -> Parser MsgId b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser MsgId MsgId
"tag: "
        Parser MsgId MsgId -> Parser MsgId MsgId -> Parser MsgId MsgId
forall a b. Parser MsgId a -> Parser MsgId b -> Parser MsgId b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (Char -> Bool) -> Parser MsgId MsgId
A.takeWhile ([Char] -> Char -> Bool
A.notInClass [Char]
" \r\n")

coreVersionInfo :: String -> CoreVersionInfo
coreVersionInfo :: [Char] -> CoreVersionInfo
coreVersionInfo [Char]
simplexmqCommit =
  CoreVersionInfo
    { version :: [Char]
version = [Char]
versionNumber,
      simplexmqVersion :: [Char]
simplexmqVersion = [Char]
simplexMQVersion,
      [Char]
simplexmqCommit :: [Char]
simplexmqCommit :: [Char]
simplexmqCommit
    }

data ChatConfig = ChatConfig
  { ChatConfig -> AgentConfig
agentConfig :: AgentConfig,
    ChatConfig -> VersionRangeChat
chatVRange :: VersionRangeChat,
    ChatConfig -> MigrationConfirmation
confirmMigrations :: MigrationConfirmation,
    ChatConfig -> PresetServers
presetServers :: PresetServers,
    ChatConfig -> NonEmpty SMPServer
shortLinkPresetServers :: NonEmpty SMPServer,
    ChatConfig -> [[Char]]
presetDomains :: [HostName],
    ChatConfig -> Natural
tbqSize :: Natural,
    ChatConfig -> Integer
fileChunkSize :: Integer,
    ChatConfig -> Int
xftpDescrPartSize :: Int,
    ChatConfig -> InlineFilesConfig
inlineFiles :: InlineFilesConfig,
    ChatConfig -> Integer
autoAcceptFileSize :: Integer,
    ChatConfig -> Bool
showReactions :: Bool,
    ChatConfig -> Bool
showReceipts :: Bool,
    ChatConfig -> Bool
subscriptionEvents :: Bool,
    ChatConfig -> Bool
hostEvents :: Bool,
    ChatConfig -> ChatLogLevel
logLevel :: ChatLogLevel,
    ChatConfig -> Bool
testView :: Bool,
    ChatConfig -> Int64
initialCleanupManagerDelay :: Int64,
    ChatConfig -> NominalDiffTime
cleanupManagerInterval :: NominalDiffTime,
    ChatConfig -> Int64
cleanupManagerStepDelay :: Int64,
    ChatConfig -> Int64
ciExpirationInterval :: Int64, -- microseconds
    ChatConfig -> Int64
deliveryWorkerDelay :: Int64, -- microseconds
    ChatConfig -> Int
deliveryBucketSize :: Int,
    ChatConfig -> Bool
highlyAvailable :: Bool,
    ChatConfig -> Text
deviceNameForRemote :: Text,
    ChatConfig -> ChatHooks
chatHooks :: ChatHooks
  }

data RandomAgentServers = RandomAgentServers
  { RandomAgentServers -> NonEmpty (ServerCfg 'PSMP)
smpServers :: NonEmpty (ServerCfg 'PSMP),
    RandomAgentServers -> NonEmpty (ServerCfg 'PXFTP)
xftpServers :: NonEmpty (ServerCfg 'PXFTP)
  }
  deriving (Int -> RandomAgentServers -> [Char] -> [Char]
[RandomAgentServers] -> [Char] -> [Char]
RandomAgentServers -> [Char]
(Int -> RandomAgentServers -> [Char] -> [Char])
-> (RandomAgentServers -> [Char])
-> ([RandomAgentServers] -> [Char] -> [Char])
-> Show RandomAgentServers
forall a.
(Int -> a -> [Char] -> [Char])
-> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
$cshowsPrec :: Int -> RandomAgentServers -> [Char] -> [Char]
showsPrec :: Int -> RandomAgentServers -> [Char] -> [Char]
$cshow :: RandomAgentServers -> [Char]
show :: RandomAgentServers -> [Char]
$cshowList :: [RandomAgentServers] -> [Char] -> [Char]
showList :: [RandomAgentServers] -> [Char] -> [Char]
Show)

-- The hooks can be used to extend or customize chat core in mobile or CLI clients.
data ChatHooks = ChatHooks
  { -- preStartHook can be used to verify some data,
    -- It is called before chat controller is started, unless the core is started in maintenance mode.
    ChatHooks -> Maybe (ChatController -> IO ())
preStartHook :: Maybe (ChatController -> IO ()),
    -- postStartHook can be used to update some data after start (e.g. commands in bot or group profiles),
    -- It is called after chat controller is started.
    ChatHooks -> Maybe (ChatController -> IO ())
postStartHook :: Maybe (ChatController -> IO ()),
    -- preCmdHook can be used to process or modify the commands before they are processed.
    -- This hook should be used to process CustomChatCommand.
    -- if this hook returns ChatResponse, the command processing will be skipped.
    ChatHooks
-> Maybe
     (ChatController
      -> ChatCommand
      -> IO (Either (Either ChatError ChatResponse) ChatCommand))
preCmdHook :: Maybe (ChatController -> ChatCommand -> IO (Either (Either ChatError ChatResponse) ChatCommand)),
    -- eventHook can be used to additionally process or modify events,
    -- it is called before the event is sent to the user (or to the UI).
    ChatHooks
-> Maybe
     (ChatController
      -> Either ChatError ChatEvent -> IO (Either ChatError ChatEvent))
eventHook :: Maybe (ChatController -> Either ChatError ChatEvent -> IO (Either ChatError ChatEvent)),
    -- acceptMember hook can be used to accept or reject member connecting via group link without API calls
    ChatHooks
-> Maybe
     (GroupInfo
      -> GroupLinkInfo
      -> Profile
      -> IO
           (Either GroupRejectionReason (GroupAcceptance, GroupMemberRole)))
acceptMember :: Maybe (GroupInfo -> GroupLinkInfo -> Profile -> IO (Either GroupRejectionReason (GroupAcceptance, GroupMemberRole)))
  }

defaultChatHooks :: ChatHooks
defaultChatHooks :: ChatHooks
defaultChatHooks = Maybe (ChatController -> IO ())
-> Maybe (ChatController -> IO ())
-> Maybe
     (ChatController
      -> ChatCommand
      -> IO (Either (Either ChatError ChatResponse) ChatCommand))
-> Maybe
     (ChatController
      -> Either ChatError ChatEvent -> IO (Either ChatError ChatEvent))
-> Maybe
     (GroupInfo
      -> GroupLinkInfo
      -> Profile
      -> IO
           (Either GroupRejectionReason (GroupAcceptance, GroupMemberRole)))
-> ChatHooks
ChatHooks Maybe (ChatController -> IO ())
forall a. Maybe a
Nothing Maybe (ChatController -> IO ())
forall a. Maybe a
Nothing Maybe
  (ChatController
   -> ChatCommand
   -> IO (Either (Either ChatError ChatResponse) ChatCommand))
forall a. Maybe a
Nothing Maybe
  (ChatController
   -> Either ChatError ChatEvent -> IO (Either ChatError ChatEvent))
forall a. Maybe a
Nothing Maybe
  (GroupInfo
   -> GroupLinkInfo
   -> Profile
   -> IO
        (Either GroupRejectionReason (GroupAcceptance, GroupMemberRole)))
forall a. Maybe a
Nothing

data PresetServers = PresetServers
  { PresetServers -> NonEmpty PresetOperator
operators :: NonEmpty PresetOperator,
    PresetServers -> [NtfServer]
ntf :: [NtfServer],
    PresetServers -> NetworkConfig
netCfg :: NetworkConfig
  }
  deriving (Int -> PresetServers -> [Char] -> [Char]
[PresetServers] -> [Char] -> [Char]
PresetServers -> [Char]
(Int -> PresetServers -> [Char] -> [Char])
-> (PresetServers -> [Char])
-> ([PresetServers] -> [Char] -> [Char])
-> Show PresetServers
forall a.
(Int -> a -> [Char] -> [Char])
-> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
$cshowsPrec :: Int -> PresetServers -> [Char] -> [Char]
showsPrec :: Int -> PresetServers -> [Char] -> [Char]
$cshow :: PresetServers -> [Char]
show :: PresetServers -> [Char]
$cshowList :: [PresetServers] -> [Char] -> [Char]
showList :: [PresetServers] -> [Char] -> [Char]
Show)

data InlineFilesConfig = InlineFilesConfig
  { InlineFilesConfig -> Integer
offerChunks :: Integer,
    InlineFilesConfig -> Integer
sendChunks :: Integer,
    InlineFilesConfig -> Integer
totalSendChunks :: Integer,
    InlineFilesConfig -> Integer
receiveChunks :: Integer,
    InlineFilesConfig -> Bool
receiveInstant :: Bool
  }

defaultInlineFilesConfig :: InlineFilesConfig
defaultInlineFilesConfig :: InlineFilesConfig
defaultInlineFilesConfig =
  InlineFilesConfig
    { offerChunks :: Integer
offerChunks = Integer
15, -- max when chunks are offered / received with the option - limited to 255 on the encoding level
      sendChunks :: Integer
sendChunks = Integer
6, -- max per file when chunks will be sent inline without acceptance
      totalSendChunks :: Integer
totalSendChunks = Integer
30, -- max per conversation when chunks will be sent inline without acceptance
      receiveChunks :: Integer
receiveChunks = Integer
8, -- max when chunks are accepted
      receiveInstant :: Bool
receiveInstant = Bool
True -- allow receiving instant files, within receiveChunks limit
    }

data ChatDatabase = ChatDatabase {ChatDatabase -> DBStore
chatStore :: DBStore, ChatDatabase -> DBStore
agentStore :: DBStore}

data ChatController = ChatController
  { ChatController -> TVar (Maybe User)
currentUser :: TVar (Maybe User),
    ChatController -> NonEmpty PresetOperator
randomPresetServers :: NonEmpty PresetOperator,
    ChatController -> RandomAgentServers
randomAgentServers :: RandomAgentServers,
    ChatController -> TVar (Maybe Int64)
currentRemoteHost :: TVar (Maybe RemoteHostId),
    ChatController -> Bool
firstTime :: Bool,
    ChatController -> AgentClient
smpAgent :: AgentClient,
    ChatController -> TVar (Maybe (Async (), Maybe (Async ())))
agentAsync :: TVar (Maybe (Async (), Maybe (Async ()))),
    ChatController -> DBStore
chatStore :: DBStore,
    ChatController -> TVar Bool
chatStoreChanged :: TVar Bool, -- if True, chat should be fully restarted
    ChatController -> TVar ChaChaDRG
random :: TVar ChaChaDRG,
    ChatController -> TVar Int
eventSeq :: TVar Int,
    ChatController -> TBQueue [Char]
inputQ :: TBQueue String,
    ChatController -> TBQueue (Maybe Int64, Either ChatError ChatEvent)
outputQ :: TBQueue (Maybe RemoteHostId, Either ChatError ChatEvent),
    ChatController -> TVar SubscriptionMode
subscriptionMode :: TVar SubscriptionMode,
    ChatController -> Lock
chatLock :: Lock,
    ChatController -> TMap ChatLockEntity Lock
entityLocks :: TMap ChatLockEntity Lock,
    ChatController -> TVar (Map Int64 Handle)
sndFiles :: TVar (Map Int64 Handle),
    ChatController -> TVar (Map Int64 Handle)
rcvFiles :: TVar (Map Int64 Handle),
    ChatController -> TMap Int64 Call
currentCalls :: TMap ContactId Call,
    ChatController -> TVar Text
localDeviceName :: TVar Text,
    ChatController -> TMVar Int
multicastSubscribers :: TMVar Int,
    ChatController -> TVar Int
remoteSessionSeq :: TVar Int,
    ChatController -> TMap RHKey (Int, RemoteHostSession)
remoteHostSessions :: TMap RHKey (SessionSeq, RemoteHostSession), -- All the active remote hosts
    ChatController -> TVar (Maybe [Char])
remoteHostsFolder :: TVar (Maybe FilePath), -- folder for remote hosts data
    ChatController -> TVar (Maybe (Int, RemoteCtrlSession))
remoteCtrlSession :: TVar (Maybe (SessionSeq, RemoteCtrlSession)), -- Supervisor process for hosted controllers
    ChatController -> ChatConfig
config :: ChatConfig,
    ChatController -> TVar (Maybe [Char])
filesFolder :: TVar (Maybe FilePath), -- path to files folder for mobile apps,
    ChatController -> TMap DeliveryWorkerKey Worker
deliveryTaskWorkers :: TMap DeliveryWorkerKey Worker,
    ChatController -> TMap DeliveryWorkerKey Worker
deliveryJobWorkers :: TMap DeliveryWorkerKey Worker,
    ChatController -> TMap Int64 (Maybe (Async ()))
expireCIThreads :: TMap UserId (Maybe (Async ())),
    ChatController -> TMap Int64 Bool
expireCIFlags :: TMap UserId Bool,
    ChatController -> TVar (Maybe (Async ()))
cleanupManagerAsync :: TVar (Maybe (Async ())),
    ChatController -> TVar Bool
chatActivated :: TVar Bool,
    ChatController
-> TMap (ChatRef, Int64) (TVar (Maybe (Weak ThreadId)))
timedItemThreads :: TMap (ChatRef, ChatItemId) (TVar (Maybe (Weak ThreadId))),
    ChatController -> TVar Bool
showLiveItems :: TVar Bool,
    ChatController -> TVar Bool
encryptLocalFiles :: TVar Bool,
    ChatController -> TVar (Maybe [Char])
tempDirectory :: TVar (Maybe FilePath),
    ChatController -> TVar (Maybe [Char])
assetsDirectory :: TVar (Maybe FilePath),
    ChatController -> Maybe [Char]
logFilePath :: Maybe FilePath,
    ChatController -> TVar Bool
contactMergeEnabled :: TVar Bool
  }

data HelpSection = HSMain | HSFiles | HSGroups | HSContacts | HSMyAddress | HSIncognito | HSMarkdown | HSMessages | HSRemote | HSSettings | HSDatabase
  deriving (Int -> HelpSection -> [Char] -> [Char]
[HelpSection] -> [Char] -> [Char]
HelpSection -> [Char]
(Int -> HelpSection -> [Char] -> [Char])
-> (HelpSection -> [Char])
-> ([HelpSection] -> [Char] -> [Char])
-> Show HelpSection
forall a.
(Int -> a -> [Char] -> [Char])
-> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
$cshowsPrec :: Int -> HelpSection -> [Char] -> [Char]
showsPrec :: Int -> HelpSection -> [Char] -> [Char]
$cshow :: HelpSection -> [Char]
show :: HelpSection -> [Char]
$cshowList :: [HelpSection] -> [Char] -> [Char]
showList :: [HelpSection] -> [Char] -> [Char]
Show)

data ChatCommand
  = ShowActiveUser
  | CreateActiveUser {ChatCommand -> NewUser
newUser :: NewUser}
  | ListUsers
  | APISetActiveUser {ChatCommand -> Int64
userId :: UserId, ChatCommand -> Maybe UserPwd
viewPwd :: Maybe UserPwd}
  | SetActiveUser UserName (Maybe UserPwd)
  | SetAllContactReceipts Bool
  | APISetUserContactReceipts UserId UserMsgReceiptSettings
  | SetUserContactReceipts UserMsgReceiptSettings
  | APISetUserGroupReceipts UserId UserMsgReceiptSettings
  | SetUserGroupReceipts UserMsgReceiptSettings
  | APISetUserAutoAcceptMemberContacts UserId Bool
  | SetUserAutoAcceptMemberContacts Bool
  | APIHideUser UserId UserPwd
  | APIUnhideUser UserId UserPwd
  | APIMuteUser UserId
  | APIUnmuteUser UserId
  | HideUser UserPwd
  | UnhideUser UserPwd
  | MuteUser
  | UnmuteUser
  | APIDeleteUser {userId :: UserId, ChatCommand -> Bool
delSMPQueues :: Bool, viewPwd :: Maybe UserPwd}
  | DeleteUser UserName Bool (Maybe UserPwd)
  | StartChat {ChatCommand -> Bool
mainApp :: Bool, ChatCommand -> Bool
enableSndFiles :: Bool} -- enableSndFiles has no effect when mainApp is True
  | CheckChatRunning
  | APIStopChat
  | APIActivateChat {ChatCommand -> Bool
restoreChat :: Bool}
  | APISuspendChat {ChatCommand -> Int
suspendTimeout :: Int}
  | ShowConnectionsDiff Bool
  | ResubscribeAllConnections
  | SetTempFolder FilePath
  | SetFilesFolder FilePath
  | SetRemoteHostsFolder FilePath
  | APISetAppFilePaths AppFilePathsConfig
  | APISetEncryptLocalFiles Bool
  | SetContactMergeEnabled Bool
#if !defined(dbPostgres)
  | APIExportArchive ArchiveConfig
  | ExportArchive
  | APIImportArchive ArchiveConfig
  | APIDeleteStorage
  | APIStorageEncryption DBEncryptionConfig
  | TestStorageEncryption DBEncryptionKey
  | SlowSQLQueries
#endif
  | ExecChatStoreSQL Text
  | ExecAgentStoreSQL Text
  | APISaveAppSettings AppSettings
  | APIGetAppSettings (Maybe AppSettings)
  | APIGetChatTags UserId
  | APIGetChats {userId :: UserId, ChatCommand -> Bool
pendingConnections :: Bool, ChatCommand -> PaginationByTime
pagination :: PaginationByTime, ChatCommand -> ChatListQuery
query :: ChatListQuery}
  | APIGetChat {ChatCommand -> ChatRef
chatRef :: ChatRef, ChatCommand -> Maybe MsgContentTag
contentTag :: Maybe MsgContentTag, ChatCommand -> ChatPagination
chatPagination :: ChatPagination, ChatCommand -> Maybe Text
search :: Maybe Text}
  | APIGetChatItems {chatPagination :: ChatPagination, search :: Maybe Text}
  | APIGetChatItemInfo {chatRef :: ChatRef, ChatCommand -> Int64
chatItemId :: ChatItemId}
  | APISendMessages {ChatCommand -> SendRef
sendRef :: SendRef, ChatCommand -> Bool
liveMessage :: Bool, ChatCommand -> Maybe Int
ttl :: Maybe Int, ChatCommand -> NonEmpty ComposedMessage
composedMessages :: NonEmpty ComposedMessage}
  | APICreateChatTag ChatTagData
  | APISetChatTags ChatRef (Maybe (NonEmpty ChatTagId))
  | APIDeleteChatTag ChatTagId
  | APIUpdateChatTag ChatTagId ChatTagData
  | APIReorderChatTags (NonEmpty ChatTagId)
  | APICreateChatItems {ChatCommand -> Int64
noteFolderId :: NoteFolderId, composedMessages :: NonEmpty ComposedMessage}
  | APIReportMessage {ChatCommand -> Int64
groupId :: GroupId, chatItemId :: ChatItemId, ChatCommand -> ReportReason
reportReason :: ReportReason, ChatCommand -> Text
reportText :: Text}
  | ReportMessage {ChatCommand -> Text
groupName :: GroupName, ChatCommand -> Maybe Text
contactName_ :: Maybe ContactName, reportReason :: ReportReason, ChatCommand -> Text
reportedMessage :: Text}
  | APIUpdateChatItem {chatRef :: ChatRef, chatItemId :: ChatItemId, liveMessage :: Bool, ChatCommand -> UpdatedMessage
updatedMessage :: UpdatedMessage}
  | APIDeleteChatItem {chatRef :: ChatRef, ChatCommand -> NonEmpty Int64
chatItemIds :: NonEmpty ChatItemId, ChatCommand -> CIDeleteMode
deleteMode :: CIDeleteMode}
  | APIDeleteMemberChatItem {groupId :: GroupId, chatItemIds :: NonEmpty ChatItemId}
  | APIArchiveReceivedReports GroupId
  | APIDeleteReceivedReports GroupId (NonEmpty ChatItemId) CIDeleteMode
  | APIChatItemReaction {chatRef :: ChatRef, chatItemId :: ChatItemId, ChatCommand -> Bool
add :: Bool, ChatCommand -> MsgReaction
reaction :: MsgReaction}
  | APIGetReactionMembers {userId :: UserId, groupId :: GroupId, chatItemId :: ChatItemId, reaction :: MsgReaction}
  | APIPlanForwardChatItems {ChatCommand -> ChatRef
fromChatRef :: ChatRef, chatItemIds :: NonEmpty ChatItemId}
  | APIForwardChatItems {ChatCommand -> ChatRef
toChatRef :: ChatRef, fromChatRef :: ChatRef, chatItemIds :: NonEmpty ChatItemId, ttl :: Maybe Int}
  | APIUserRead UserId
  | UserRead
  | APIChatRead {chatRef :: ChatRef}
  | APIChatItemsRead {chatRef :: ChatRef, chatItemIds :: NonEmpty ChatItemId}
  | APIChatUnread {chatRef :: ChatRef, ChatCommand -> Bool
unreadChat :: Bool}
  | APIDeleteChat {chatRef :: ChatRef, ChatCommand -> ChatDeleteMode
chatDeleteMode :: ChatDeleteMode} -- currently delete mode settings are only applied to direct chats
  | APIClearChat {chatRef :: ChatRef}
  | APIAcceptContact {ChatCommand -> Bool
incognito :: IncognitoEnabled, ChatCommand -> Int64
contactReqId :: Int64}
  | APIRejectContact {contactReqId :: Int64}
  | APISendCallInvitation ContactId CallType
  | SendCallInvitation ContactName CallType
  | APIRejectCall ContactId
  | APISendCallOffer ContactId WebRTCCallOffer
  | APISendCallAnswer ContactId WebRTCSession
  | APISendCallExtraInfo ContactId WebRTCExtraInfo
  | APIEndCall ContactId
  | APIGetCallInvitations
  | APICallStatus ContactId WebRTCCallStatus
  | APIUpdateProfile {userId :: UserId, ChatCommand -> Profile
profile :: Profile}
  | APISetContactPrefs {ChatCommand -> Int64
contactId :: ContactId, ChatCommand -> Preferences
preferences :: Preferences}
  | APISetContactAlias {contactId :: ContactId, ChatCommand -> Text
localAlias :: LocalAlias}
  | APISetGroupAlias {groupId :: GroupId, localAlias :: LocalAlias}
  | APISetConnectionAlias {ChatCommand -> Int64
connectionId :: Int64, localAlias :: LocalAlias}
  | APISetUserUIThemes UserId (Maybe UIThemeEntityOverrides)
  | APISetChatUIThemes ChatRef (Maybe UIThemeEntityOverrides)
  | APIGetNtfToken
  | APIRegisterToken DeviceToken NotificationsMode
  | APIVerifyToken DeviceToken C.CbNonce ByteString
  | APICheckToken DeviceToken
  | APIDeleteToken DeviceToken
  | APIGetNtfConns {ChatCommand -> CbNonce
nonce :: C.CbNonce, ChatCommand -> MsgId
encNtfInfo :: ByteString}
  | APIGetConnNtfMessages (NonEmpty ConnMsgReq)
  | APIAddMember {groupId :: GroupId, contactId :: ContactId, ChatCommand -> GroupMemberRole
memberRole :: GroupMemberRole}
  | APIJoinGroup {groupId :: GroupId, ChatCommand -> MsgFilter
enableNtfs :: MsgFilter}
  | APIAcceptMember {groupId :: GroupId, ChatCommand -> Int64
groupMemberId :: GroupMemberId, memberRole :: GroupMemberRole}
  | APIDeleteMemberSupportChat GroupId GroupMemberId
  | APIMembersRole {groupId :: GroupId, ChatCommand -> NonEmpty Int64
groupMemberIds :: NonEmpty GroupMemberId, memberRole :: GroupMemberRole}
  | APIBlockMembersForAll {groupId :: GroupId, groupMemberIds :: NonEmpty GroupMemberId, ChatCommand -> Bool
blocked :: Bool}
  | APIRemoveMembers {groupId :: GroupId, groupMemberIds :: NonEmpty GroupMemberId, ChatCommand -> Bool
withMessages :: Bool}
  | APILeaveGroup {groupId :: GroupId}
  | APIListMembers {groupId :: GroupId}
  | APIUpdateGroupProfile {groupId :: GroupId, ChatCommand -> GroupProfile
groupProfile :: GroupProfile}
  | APICreateGroupLink {groupId :: GroupId, memberRole :: GroupMemberRole}
  | APIGroupLinkMemberRole {groupId :: GroupId, memberRole :: GroupMemberRole}
  | APIDeleteGroupLink {groupId :: GroupId}
  | APIGetGroupLink {groupId :: GroupId}
  | APIAddGroupShortLink GroupId
  | APICreateMemberContact GroupId GroupMemberId
  | APISendMemberContactInvitation {contactId :: ContactId, ChatCommand -> Maybe MsgContent
msgContent_ :: Maybe MsgContent}
  | APIAcceptMemberContact ContactId
  | GetUserProtoServers AProtocolType
  | SetUserProtoServers AProtocolType [AProtoServerWithAuth]
  | APITestProtoServer UserId AProtoServerWithAuth
  | TestProtoServer AProtoServerWithAuth
  | APIGetServerOperators
  | APISetServerOperators (NonEmpty ServerOperator)
  | SetServerOperators (NonEmpty ServerOperatorRoles)
  | APIGetUserServers UserId
  | APISetUserServers UserId (NonEmpty UpdatedUserOperatorServers)
  | APIValidateServers UserId [UpdatedUserOperatorServers] -- response is CRUserServersValidation
  | APIGetUsageConditions
  | APISetConditionsNotified Int64
  | APIAcceptConditions Int64 (NonEmpty Int64)
  | APISetChatItemTTL UserId Int64
  | SetChatItemTTL Int64
  | APIGetChatItemTTL UserId
  | GetChatItemTTL
  | APISetChatTTL {userId :: UserId, chatRef :: ChatRef, ChatCommand -> Maybe Int64
seconds :: Maybe Int64}
  | SetChatTTL ChatName (Maybe Int64)
  | GetChatTTL ChatName
  | APISetNetworkConfig NetworkConfig
  | APIGetNetworkConfig
  | SetNetworkConfig SimpleNetCfg
  | APISetNetworkInfo UserNetworkInfo
  | ReconnectAllServers
  | ReconnectServer UserId SMPServer
  | APISetChatSettings {chatRef :: ChatRef, ChatCommand -> ChatSettings
chatSettings :: ChatSettings}
  | APISetMemberSettings GroupId GroupMemberId GroupMemberSettings
  | APIContactInfo ContactId
  | APIGroupInfo GroupId
  | APIGroupMemberInfo GroupId GroupMemberId
  | APIContactQueueInfo ContactId
  | APIGroupMemberQueueInfo GroupId GroupMemberId
  | APISwitchContact ContactId
  | APISwitchGroupMember GroupId GroupMemberId
  | APIAbortSwitchContact ContactId
  | APIAbortSwitchGroupMember GroupId GroupMemberId
  | APISyncContactRatchet {contactId :: ContactId, ChatCommand -> Bool
force :: Bool}
  | APISyncGroupMemberRatchet {groupId :: GroupId, groupMemberId :: GroupMemberId, force :: Bool}
  | APIGetContactCode ContactId
  | APIGetGroupMemberCode GroupId GroupMemberId
  | APIVerifyContact ContactId (Maybe Text)
  | APIVerifyGroupMember GroupId GroupMemberId (Maybe Text)
  | APIEnableContact ContactId
  | APIEnableGroupMember GroupId GroupMemberId
  | SetShowMessages ChatName MsgFilter
  | SetSendReceipts ChatName (Maybe Bool)
  | SetShowMemberMessages GroupName ContactName Bool
  | ContactInfo ContactName
  | ShowGroupInfo GroupName
  | GroupMemberInfo GroupName ContactName
  | ContactQueueInfo ContactName
  | GroupMemberQueueInfo GroupName ContactName
  | SwitchContact ContactName
  | SwitchGroupMember GroupName ContactName
  | AbortSwitchContact ContactName
  | AbortSwitchGroupMember GroupName ContactName
  | SyncContactRatchet ContactName Bool
  | SyncGroupMemberRatchet GroupName ContactName Bool
  | GetContactCode ContactName
  | GetGroupMemberCode GroupName ContactName
  | VerifyContact ContactName (Maybe Text)
  | VerifyGroupMember GroupName ContactName (Maybe Text)
  | EnableContact ContactName
  | EnableGroupMember GroupName ContactName
  | ChatHelp HelpSection
  | Welcome
  | APIAddContact {userId :: UserId, incognito :: IncognitoEnabled}
  | AddContact IncognitoEnabled
  | APISetConnectionIncognito Int64 IncognitoEnabled
  | APIChangeConnectionUser Int64 UserId -- new user id to switch connection to
  | APIConnectPlan {userId :: UserId, ChatCommand -> Maybe AConnectionLink
connectionLink :: Maybe AConnectionLink} -- Maybe is used to report link parsing failure as special error
  | APIPrepareContact UserId ACreatedConnLink ContactShortLinkData
  | APIPrepareGroup UserId CreatedLinkContact GroupShortLinkData
  | APIChangePreparedContactUser ContactId UserId
  | APIChangePreparedGroupUser GroupId UserId
  | APIConnectPreparedContact {contactId :: ContactId, incognito :: IncognitoEnabled, msgContent_ :: Maybe MsgContent}
  | APIConnectPreparedGroup GroupId IncognitoEnabled (Maybe MsgContent)
  | APIConnect {userId :: UserId, incognito :: IncognitoEnabled, ChatCommand -> Maybe ACreatedConnLink
preparedLink_ :: Maybe ACreatedConnLink} -- Maybe is used to report link parsing failure as special error
  | Connect {incognito :: IncognitoEnabled, ChatCommand -> Maybe AConnectionLink
connLink_ :: Maybe AConnectionLink}
  | APIConnectContactViaAddress UserId IncognitoEnabled ContactId
  | ConnectSimplex IncognitoEnabled -- UserId (not used in UI)
  | DeleteContact ContactName ChatDeleteMode
  | ClearContact ContactName
  | APIListContacts {userId :: UserId}
  | ListContacts
  | APICreateMyAddress {userId :: UserId}
  | CreateMyAddress
  | APIDeleteMyAddress {userId :: UserId}
  | DeleteMyAddress
  | APIShowMyAddress {userId :: UserId}
  | ShowMyAddress
  | APIAddMyAddressShortLink UserId
  | APISetProfileAddress {userId :: UserId, ChatCommand -> Bool
enable :: Bool}
  | SetProfileAddress Bool
  | APISetAddressSettings {userId :: UserId, ChatCommand -> AddressSettings
settings :: AddressSettings}
  | SetAddressSettings AddressSettings
  | AcceptContact IncognitoEnabled ContactName
  | RejectContact ContactName
  | ForwardMessage {ChatCommand -> ChatName
toChatName :: ChatName, ChatCommand -> Text
fromContactName :: ContactName, ChatCommand -> Text
forwardedMsg :: Text}
  | ForwardGroupMessage {toChatName :: ChatName, ChatCommand -> Text
fromGroupName :: GroupName, ChatCommand -> Maybe Text
fromMemberName_ :: Maybe ContactName, forwardedMsg :: Text}
  | ForwardLocalMessage {toChatName :: ChatName, forwardedMsg :: Text}
  | SendMessage SendName Text
  | SendMemberContactMessage GroupName ContactName Text
  | AcceptMemberContact ContactName
  | SendLiveMessage ChatName Text
  | SendMessageQuote {ChatCommand -> Text
contactName :: ContactName, ChatCommand -> AMsgDirection
msgDir :: AMsgDirection, ChatCommand -> Text
quotedMsg :: Text, ChatCommand -> Text
message :: Text}
  | SendMessageBroadcast MsgContent -- UserId (not used in UI)
  | DeleteMessage ChatName Text
  | DeleteMemberMessage GroupName ContactName Text
  | EditMessage {ChatCommand -> ChatName
chatName :: ChatName, ChatCommand -> Text
editedMsg :: Text, message :: Text}
  | UpdateLiveMessage {chatName :: ChatName, chatItemId :: ChatItemId, liveMessage :: Bool, message :: Text}
  | ReactToMessage {add :: Bool, reaction :: MsgReaction, chatName :: ChatName, ChatCommand -> Text
reactToMessage :: Text}
  | APINewGroup {userId :: UserId, incognito :: IncognitoEnabled, groupProfile :: GroupProfile}
  | NewGroup IncognitoEnabled GroupProfile
  | AddMember GroupName ContactName GroupMemberRole
  | JoinGroup {groupName :: GroupName, enableNtfs :: MsgFilter}
  | AcceptMember GroupName ContactName GroupMemberRole
  | MemberRole GroupName ContactName GroupMemberRole
  | BlockForAll GroupName ContactName Bool
  | RemoveMembers {groupName :: GroupName, ChatCommand -> NonEmpty Text
members :: NonEmpty ContactName, withMessages :: Bool}
  | LeaveGroup GroupName
  | DeleteGroup GroupName
  | ClearGroup GroupName
  | ListMembers GroupName
  | ListMemberSupportChats GroupName
  | APIListGroups {userId :: UserId, ChatCommand -> Maybe Int64
contactId_ :: Maybe ContactId, search :: Maybe Text}
  | ListGroups (Maybe ContactName) (Maybe Text)
  | UpdateGroupNames GroupName GroupProfile
  | ShowGroupProfile GroupName
  | UpdateGroupDescription GroupName (Maybe Text)
  | ShowGroupDescription GroupName
  | CreateGroupLink GroupName GroupMemberRole
  | GroupLinkMemberRole GroupName GroupMemberRole
  | DeleteGroupLink GroupName
  | ShowGroupLink GroupName
  | SendGroupMessageQuote {groupName :: GroupName, contactName_ :: Maybe ContactName, quotedMsg :: Text, message :: Text}
  | ClearNoteFolder
  | LastChats (Maybe Int) -- UserId (not used in UI)
  | LastMessages (Maybe ChatName) Int (Maybe Text) -- UserId (not used in UI)
  | LastChatItemId (Maybe ChatName) Int -- UserId (not used in UI)
  | ShowChatItem (Maybe ChatItemId) -- UserId (not used in UI)
  | ShowChatItemInfo ChatName Text
  | ShowLiveItems Bool
  | SendFile ChatName CryptoFile
  | SendImage ChatName CryptoFile
  | ForwardFile ChatName FileTransferId
  | ForwardImage ChatName FileTransferId
  | SendFileDescription ChatName FilePath
  | ReceiveFile {ChatCommand -> Int64
fileId :: FileTransferId, ChatCommand -> Bool
userApprovedRelays :: Bool, ChatCommand -> Maybe Bool
storeEncrypted :: Maybe Bool, ChatCommand -> Maybe Bool
fileInline :: Maybe Bool, ChatCommand -> Maybe [Char]
filePath :: Maybe FilePath}
  | SetFileToReceive {fileId :: FileTransferId, userApprovedRelays :: Bool, storeEncrypted :: Maybe Bool}
  | CancelFile {fileId :: FileTransferId}
  | FileStatus FileTransferId
  | ShowProfile -- UserId (not used in UI)
  | SetBotCommands [ChatBotCommand]
  | UpdateProfile ContactName (Maybe Text) -- UserId (not used in UI)
  | UpdateProfileImage (Maybe ImageData) -- UserId (not used in UI)
  | ShowProfileImage
  | SetUserFeature AChatFeature FeatureAllowed -- UserId (not used in UI)
  | SetContactFeature AChatFeature ContactName (Maybe FeatureAllowed)
  | SetGroupFeature AGroupFeatureNoRole GroupName GroupFeatureEnabled
  | SetGroupFeatureRole AGroupFeatureRole GroupName GroupFeatureEnabled (Maybe GroupMemberRole)
  | SetGroupMemberAdmissionReview GroupName (Maybe MemberCriteria)
  | SetUserTimedMessages Bool -- UserId (not used in UI)
  | SetContactTimedMessages ContactName (Maybe TimedMessagesEnabled)
  | SetGroupTimedMessages GroupName (Maybe Int)
  | SetLocalDeviceName Text
  | ListRemoteHosts
  | StartRemoteHost (Maybe (RemoteHostId, Bool)) (Maybe RCCtrlAddress) (Maybe Word16) -- Start new or known remote host with optional multicast for known host
  | SwitchRemoteHost (Maybe RemoteHostId) -- Switch current remote host
  | StopRemoteHost RHKey -- Shut down a running session
  | DeleteRemoteHost RemoteHostId -- Unregister remote host and remove its data
  | StoreRemoteFile {ChatCommand -> Int64
remoteHostId :: RemoteHostId, storeEncrypted :: Maybe Bool, ChatCommand -> [Char]
localPath :: FilePath}
  | GetRemoteFile {remoteHostId :: RemoteHostId, ChatCommand -> RemoteFile
file :: RemoteFile}
  | ConnectRemoteCtrl RCSignedInvitation -- Connect new or existing controller via OOB data
  | FindKnownRemoteCtrl -- Start listening for announcements from all existing controllers
  | ConfirmRemoteCtrl RemoteCtrlId -- Confirm the connection with found controller
  | VerifyRemoteCtrlSession Text -- Verify remote controller session
  | ListRemoteCtrls
  | StopRemoteCtrl -- Stop listening for announcements or terminate an active session
  | DeleteRemoteCtrl RemoteCtrlId -- Remove all local data associated with a remote controller session
  | APIUploadStandaloneFile UserId CryptoFile
  | APIDownloadStandaloneFile UserId FileDescriptionURI CryptoFile
  | APIStandaloneFileInfo FileDescriptionURI
  | QuitChat
  | ShowVersion
  | DebugLocks
  | DebugEvent ChatEvent
  | GetAgentSubsTotal UserId
  | GetAgentServersSummary UserId
  | ResetAgentServersStats
  | GetAgentSubs
  | GetAgentSubsDetails
  | GetAgentWorkers
  | GetAgentWorkersDetails
  | GetAgentQueuesInfo
  | -- The parser will return this command for strings that start from "//".
    -- This command should be processed in preCmdHook
    CustomChatCommand ByteString
  deriving (Int -> ChatCommand -> [Char] -> [Char]
[ChatCommand] -> [Char] -> [Char]
ChatCommand -> [Char]
(Int -> ChatCommand -> [Char] -> [Char])
-> (ChatCommand -> [Char])
-> ([ChatCommand] -> [Char] -> [Char])
-> Show ChatCommand
forall a.
(Int -> a -> [Char] -> [Char])
-> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
$cshowsPrec :: Int -> ChatCommand -> [Char] -> [Char]
showsPrec :: Int -> ChatCommand -> [Char] -> [Char]
$cshow :: ChatCommand -> [Char]
show :: ChatCommand -> [Char]
$cshowList :: [ChatCommand] -> [Char] -> [Char]
showList :: [ChatCommand] -> [Char] -> [Char]
Show)

allowRemoteCommand :: ChatCommand -> Bool -- XXX: consider using Relay/Block/ForceLocal
allowRemoteCommand :: ChatCommand -> Bool
allowRemoteCommand = \case
  StartChat {} -> Bool
False
  ChatCommand
APIStopChat -> Bool
False
  APIActivateChat Bool
_ -> Bool
False
  APISuspendChat Int
_ -> Bool
False
  ChatCommand
QuitChat -> Bool
False
  SetTempFolder [Char]
_ -> Bool
False
  SetFilesFolder [Char]
_ -> Bool
False
  SetRemoteHostsFolder [Char]
_ -> Bool
False
  APISetEncryptLocalFiles Bool
_ -> Bool
False
#if !defined(dbPostgres)
  APIExportArchive ArchiveConfig
_ -> Bool
False
  APIImportArchive ArchiveConfig
_ -> Bool
False
  ChatCommand
ExportArchive -> Bool
False
  ChatCommand
APIDeleteStorage -> Bool
False
  APIStorageEncryption DBEncryptionConfig
_ -> Bool
False
  ChatCommand
SlowSQLQueries -> Bool
False
#endif
  APISetNetworkConfig NetworkConfig
_ -> Bool
False
  ChatCommand
APIGetNetworkConfig -> Bool
False
  SetLocalDeviceName Text
_ -> Bool
False
  ChatCommand
ListRemoteHosts -> Bool
False
  StartRemoteHost {} -> Bool
False
  SwitchRemoteHost {} -> Bool
False
  StoreRemoteFile {} -> Bool
False
  GetRemoteFile {} -> Bool
False
  StopRemoteHost RHKey
_ -> Bool
False
  DeleteRemoteHost Int64
_ -> Bool
False
  ConnectRemoteCtrl {} -> Bool
False
  ChatCommand
FindKnownRemoteCtrl -> Bool
False
  ConfirmRemoteCtrl Int64
_ -> Bool
False
  VerifyRemoteCtrlSession {} -> Bool
False
  ChatCommand
ListRemoteCtrls -> Bool
False
  ChatCommand
StopRemoteCtrl -> Bool
False
  DeleteRemoteCtrl Int64
_ -> Bool
False
  ExecChatStoreSQL Text
_ -> Bool
False
  ExecAgentStoreSQL Text
_ -> Bool
False
  ChatCommand
_ -> Bool
True

data ChatResponse
  = CRActiveUser {ChatResponse -> User
user :: User}
  | CRUsersList {ChatResponse -> [UserInfo]
users :: [UserInfo]}
  | CRChatStarted
  | CRChatRunning
  | CRChatStopped
  | CRConnectionsDiff {ChatResponse -> Bool
showIds :: Bool, ChatResponse -> DatabaseDiff AgentUserId
userIds :: DatabaseDiff AgentUserId, ChatResponse -> DatabaseDiff AgentConnId
connIds :: DatabaseDiff AgentConnId}
  | CRApiChats {user :: User, ChatResponse -> [AChat]
chats :: [AChat]}
  | CRChats {chats :: [AChat]}
  | CRApiChat {user :: User, ChatResponse -> AChat
chat :: AChat, ChatResponse -> Maybe NavigationInfo
navInfo :: Maybe NavigationInfo}
  | CRChatTags {user :: User, ChatResponse -> [ChatTag]
userTags :: [ChatTag]}
  | CRChatItems {user :: User, ChatResponse -> Maybe ChatName
chatName_ :: Maybe ChatName, ChatResponse -> [AChatItem]
chatItems :: [AChatItem]}
  | CRChatItemInfo {user :: User, ChatResponse -> AChatItem
chatItem :: AChatItem, ChatResponse -> ChatItemInfo
chatItemInfo :: ChatItemInfo}
  | CRChatItemId User (Maybe ChatItemId)
  | CRServerTestResult {user :: User, ChatResponse -> AProtoServerWithAuth
testServer :: AProtoServerWithAuth, ChatResponse -> Maybe ProtocolTestFailure
testFailure :: Maybe ProtocolTestFailure}
  | CRServerOperatorConditions {ChatResponse -> ServerOperatorConditions
conditions :: ServerOperatorConditions}
  | CRUserServers {user :: User, ChatResponse -> [UserOperatorServers]
userServers :: [UserOperatorServers]}
  | CRUserServersValidation {user :: User, ChatResponse -> [UserServersError]
serverErrors :: [UserServersError]}
  | CRUsageConditions {ChatResponse -> UsageConditions
usageConditions :: UsageConditions, ChatResponse -> Text
conditionsText :: Text, ChatResponse -> Maybe UsageConditions
acceptedConditions :: Maybe UsageConditions}
  | CRChatItemTTL {user :: User, ChatResponse -> Maybe Int64
chatItemTTL :: Maybe Int64}
  | CRNetworkConfig {ChatResponse -> NetworkConfig
networkConfig :: NetworkConfig}
  | CRContactInfo {user :: User, ChatResponse -> Contact
contact :: Contact, ChatResponse -> Maybe ConnectionStats
connectionStats_ :: Maybe ConnectionStats, ChatResponse -> Maybe Profile
customUserProfile :: Maybe Profile}
  | CRGroupInfo {user :: User, ChatResponse -> GroupInfo
groupInfo :: GroupInfo}
  | CRGroupMemberInfo {user :: User, groupInfo :: GroupInfo, ChatResponse -> GroupMember
member :: GroupMember, connectionStats_ :: Maybe ConnectionStats}
  | CRQueueInfo {user :: User, ChatResponse -> Maybe RcvMsgInfo
rcvMsgInfo :: Maybe RcvMsgInfo, ChatResponse -> ServerQueueInfo
queueInfo :: ServerQueueInfo}
  | CRContactSwitchStarted {user :: User, contact :: Contact, ChatResponse -> ConnectionStats
connectionStats :: ConnectionStats}
  | CRGroupMemberSwitchStarted {user :: User, groupInfo :: GroupInfo, member :: GroupMember, connectionStats :: ConnectionStats}
  | CRContactSwitchAborted {user :: User, contact :: Contact, connectionStats :: ConnectionStats}
  | CRGroupMemberSwitchAborted {user :: User, groupInfo :: GroupInfo, member :: GroupMember, connectionStats :: ConnectionStats}
  | CRContactRatchetSyncStarted {user :: User, contact :: Contact, connectionStats :: ConnectionStats}
  | CRGroupMemberRatchetSyncStarted {user :: User, groupInfo :: GroupInfo, member :: GroupMember, connectionStats :: ConnectionStats}
  | CRContactCode {user :: User, contact :: Contact, ChatResponse -> Text
connectionCode :: Text}
  | CRGroupMemberCode {user :: User, groupInfo :: GroupInfo, member :: GroupMember, connectionCode :: Text}
  | CRConnectionVerified {user :: User, ChatResponse -> Bool
verified :: Bool, ChatResponse -> Text
expectedCode :: Text}
  | CRTagsUpdated {user :: User, userTags :: [ChatTag], ChatResponse -> [Int64]
chatTags :: [ChatTagId]}
  | CRNewChatItems {user :: User, chatItems :: [AChatItem]}
  | CRChatItemUpdated {user :: User, chatItem :: AChatItem}
  | CRChatItemNotChanged {user :: User, chatItem :: AChatItem}
  | CRChatItemReaction {user :: User, ChatResponse -> Bool
added :: Bool, ChatResponse -> ACIReaction
reaction :: ACIReaction}
  | CRReactionMembers {user :: User, ChatResponse -> [MemberReaction]
memberReactions :: [MemberReaction]}
  | CRChatItemsDeleted {user :: User, ChatResponse -> [ChatItemDeletion]
chatItemDeletions :: [ChatItemDeletion], ChatResponse -> Bool
byUser :: Bool, ChatResponse -> Bool
timed :: Bool}
  | CRGroupChatItemsDeleted {user :: User, groupInfo :: GroupInfo, ChatResponse -> [Int64]
chatItemIDs :: [ChatItemId], byUser :: Bool, ChatResponse -> Maybe GroupMember
member_ :: Maybe GroupMember}
  | CRBroadcastSent {user :: User, ChatResponse -> MsgContent
msgContent :: MsgContent, ChatResponse -> Int
successes :: Int, ChatResponse -> Int
failures :: Int, ChatResponse -> UTCTime
timestamp :: UTCTime}
  | CRCmdOk {ChatResponse -> Maybe User
user_ :: Maybe User}
  | CRChatHelp {ChatResponse -> HelpSection
helpSection :: HelpSection}
  | CRWelcome {user :: User}
  | CRGroupCreated {user :: User, groupInfo :: GroupInfo}
  | CRGroupMembers {user :: User, ChatResponse -> Group
group :: Group}
  | CRMemberSupportChats {user :: User, groupInfo :: GroupInfo, ChatResponse -> [GroupMember]
members :: [GroupMember]}
  -- | CRGroupConversationsArchived {user :: User, groupInfo :: GroupInfo, archivedGroupConversations :: [GroupConversation]}
  -- | CRGroupConversationsDeleted {user :: User, groupInfo :: GroupInfo, deletedGroupConversations :: [GroupConversation]}
  | CRContactsList {user :: User, ChatResponse -> [Contact]
contacts :: [Contact]}
  | CRUserContactLink {user :: User, ChatResponse -> UserContactLink
contactLink :: UserContactLink}
  | CRUserContactLinkUpdated {user :: User, contactLink :: UserContactLink}
  | CRContactRequestRejected {user :: User, ChatResponse -> UserContactRequest
contactRequest :: UserContactRequest, ChatResponse -> Maybe Contact
contact_ :: Maybe Contact}
  | CRUserAcceptedGroupSent {user :: User, groupInfo :: GroupInfo, ChatResponse -> Maybe Contact
hostContact :: Maybe Contact}
  | CRUserDeletedMembers {user :: User, groupInfo :: GroupInfo, members :: [GroupMember], ChatResponse -> Bool
withMessages :: Bool}
  | CRGroupsList {user :: User, ChatResponse -> [GroupInfo]
groups :: [GroupInfo]}
  | CRSentGroupInvitation {user :: User, groupInfo :: GroupInfo, contact :: Contact, member :: GroupMember}
  | CRFileTransferStatus User (FileTransfer, [Integer]) -- TODO refactor this type to FileTransferStatus
  | CRFileTransferStatusXFTP User AChatItem
  | CRUserProfile {user :: User, ChatResponse -> Profile
profile :: Profile}
  | CRUserProfileNoChange {user :: User}
  | CRUserPrivacy {user :: User, ChatResponse -> User
updatedUser :: User}
  | CRVersionInfo {ChatResponse -> CoreVersionInfo
versionInfo :: CoreVersionInfo, ChatResponse -> [UpMigration]
chatMigrations :: [UpMigration], ChatResponse -> [UpMigration]
agentMigrations :: [UpMigration]}
  | CRInvitation {user :: User, ChatResponse -> CreatedLinkInvitation
connLinkInvitation :: CreatedLinkInvitation, ChatResponse -> PendingContactConnection
connection :: PendingContactConnection}
  | CRConnectionIncognitoUpdated {user :: User, ChatResponse -> PendingContactConnection
toConnection :: PendingContactConnection, customUserProfile :: Maybe Profile}
  | CRConnectionUserChanged {user :: User, ChatResponse -> PendingContactConnection
fromConnection :: PendingContactConnection, toConnection :: PendingContactConnection, ChatResponse -> User
newUser :: User}
  | CRConnectionPlan {user :: User, ChatResponse -> ACreatedConnLink
connLink :: ACreatedConnLink, ChatResponse -> ConnectionPlan
connectionPlan :: ConnectionPlan}
  | CRNewPreparedChat {user :: User, chat :: AChat}
  | CRContactUserChanged {user :: User, ChatResponse -> Contact
fromContact :: Contact, newUser :: User, ChatResponse -> Contact
toContact :: Contact}
  | CRGroupUserChanged {user :: User, ChatResponse -> GroupInfo
fromGroup :: GroupInfo, newUser :: User, ChatResponse -> GroupInfo
toGroup :: GroupInfo}
  | CRSentConfirmation {user :: User, connection :: PendingContactConnection, customUserProfile :: Maybe Profile}
  | CRSentInvitation {user :: User, connection :: PendingContactConnection, customUserProfile :: Maybe Profile}
  | CRStartedConnectionToContact {user :: User, contact :: Contact, customUserProfile :: Maybe Profile}
  | CRStartedConnectionToGroup {user :: User, groupInfo :: GroupInfo, customUserProfile :: Maybe Profile}
  | CRSentInvitationToContact {user :: User, contact :: Contact, customUserProfile :: Maybe Profile}
  | CRItemsReadForChat {user :: User, ChatResponse -> AChatInfo
chatInfo :: AChatInfo}
  | CRContactDeleted {user :: User, contact :: Contact}
  | CRChatCleared {user :: User, chatInfo :: AChatInfo}
  | CRUserContactLinkCreated {user :: User, ChatResponse -> CreatedLinkContact
connLinkContact :: CreatedLinkContact}
  | CRUserContactLinkDeleted {user :: User}
  | CRAcceptingContactRequest {user :: User, contact :: Contact}
  | CRContactAlreadyExists {user :: User, contact :: Contact}
  | CRLeftMemberUser {user :: User, groupInfo :: GroupInfo}
  | CRGroupDeletedUser {user :: User, groupInfo :: GroupInfo}
  | CRForwardPlan {user :: User, ChatResponse -> Int
itemsCount :: Int, ChatResponse -> [Int64]
chatItemIds :: [ChatItemId], ChatResponse -> Maybe ForwardConfirmation
forwardConfirmation :: Maybe ForwardConfirmation}
  | CRRcvFileAccepted {user :: User, chatItem :: AChatItem}
  -- TODO add chatItem :: AChatItem
  | CRRcvFileAcceptedSndCancelled {user :: User, ChatResponse -> RcvFileTransfer
rcvFileTransfer :: RcvFileTransfer}
  | CRStandaloneFileInfo {ChatResponse -> Maybe Value
fileMeta :: Maybe J.Value}
  | CRRcvStandaloneFileCreated {user :: User, rcvFileTransfer :: RcvFileTransfer} -- returned by _download
  | CRRcvFileCancelled {user :: User, ChatResponse -> Maybe AChatItem
chatItem_ :: Maybe AChatItem, rcvFileTransfer :: RcvFileTransfer}
  | CRSndFileCancelled {user :: User, chatItem_ :: Maybe AChatItem, ChatResponse -> FileTransferMeta
fileTransferMeta :: FileTransferMeta, ChatResponse -> [SndFileTransfer]
sndFileTransfers :: [SndFileTransfer]}
  | CRSndStandaloneFileCreated {user :: User, fileTransferMeta :: FileTransferMeta} -- returned by _upload
  | CRUserProfileUpdated {user :: User, ChatResponse -> Profile
fromProfile :: Profile, ChatResponse -> Profile
toProfile :: Profile, ChatResponse -> UserProfileUpdateSummary
updateSummary :: UserProfileUpdateSummary}
  | CRUserProfileImage {user :: User, profile :: Profile}
  | CRContactAliasUpdated {user :: User, toContact :: Contact}
  | CRGroupAliasUpdated {user :: User, toGroup :: GroupInfo}
  | CRConnectionAliasUpdated {user :: User, toConnection :: PendingContactConnection}
  | CRContactPrefsUpdated {user :: User, fromContact :: Contact, toContact :: Contact}
  | CRJoinedGroupMember {user :: User, groupInfo :: GroupInfo, member :: GroupMember}
  | CRMemberAccepted {user :: User, groupInfo :: GroupInfo, member :: GroupMember}
  | CRMemberSupportChatRead {user :: User, groupInfo :: GroupInfo, member :: GroupMember}
  | CRMemberSupportChatDeleted {user :: User, groupInfo :: GroupInfo, member :: GroupMember}
  | CRMembersRoleUser {user :: User, groupInfo :: GroupInfo, members :: [GroupMember], ChatResponse -> GroupMemberRole
toRole :: GroupMemberRole}
  | CRMembersBlockedForAllUser {user :: User, groupInfo :: GroupInfo, members :: [GroupMember], ChatResponse -> Bool
blocked :: Bool}
  | CRGroupUpdated {user :: User, fromGroup :: GroupInfo, toGroup :: GroupInfo, member_ :: Maybe GroupMember}
  | CRGroupProfile {user :: User, groupInfo :: GroupInfo}
  | CRGroupDescription {user :: User, groupInfo :: GroupInfo} -- only used in CLI
  | CRGroupLinkCreated {user :: User, groupInfo :: GroupInfo, ChatResponse -> GroupLink
groupLink :: GroupLink}
  | CRGroupLink {user :: User, groupInfo :: GroupInfo, groupLink :: GroupLink}
  | CRGroupLinkDeleted {user :: User, groupInfo :: GroupInfo}
  | CRNewMemberContact {user :: User, contact :: Contact, groupInfo :: GroupInfo, member :: GroupMember}
  | CRNewMemberContactSentInv {user :: User, contact :: Contact, groupInfo :: GroupInfo, member :: GroupMember}
  | CRMemberContactAccepted {user :: User, contact :: Contact}
  | CRCallInvitations {ChatResponse -> [RcvCallInvitation]
callInvitations :: [RcvCallInvitation]}
  | CRNtfTokenStatus {ChatResponse -> NtfTknStatus
status :: NtfTknStatus}
  | CRNtfToken {ChatResponse -> DeviceToken
token :: DeviceToken, status :: NtfTknStatus, ChatResponse -> NotificationsMode
ntfMode :: NotificationsMode, ChatResponse -> NtfServer
ntfServer :: NtfServer}
  | CRNtfConns {ChatResponse -> [NtfConn]
ntfConns :: [NtfConn]}
  | CRConnNtfMessages {ChatResponse -> NonEmpty RcvNtfMsgInfo
receivedMsgs :: NonEmpty RcvNtfMsgInfo}
  | CRContactConnectionDeleted {user :: User, connection :: PendingContactConnection}
  | CRRemoteHostList {ChatResponse -> [RemoteHostInfo]
remoteHosts :: [RemoteHostInfo]}
  | CRCurrentRemoteHost {ChatResponse -> Maybe RemoteHostInfo
remoteHost_ :: Maybe RemoteHostInfo}
  | CRRemoteHostStarted {remoteHost_ :: Maybe RemoteHostInfo, ChatResponse -> Text
invitation :: Text, ChatResponse -> [Char]
ctrlPort :: String, ChatResponse -> NonEmpty RCCtrlAddress
localAddrs :: NonEmpty RCCtrlAddress}
  | CRRemoteFileStored {ChatResponse -> Int64
remoteHostId :: RemoteHostId, ChatResponse -> CryptoFile
remoteFileSource :: CryptoFile}
  | CRRemoteCtrlList {ChatResponse -> [RemoteCtrlInfo]
remoteCtrls :: [RemoteCtrlInfo]}
  | CRRemoteCtrlConnecting {ChatResponse -> Maybe RemoteCtrlInfo
remoteCtrl_ :: Maybe RemoteCtrlInfo, ChatResponse -> CtrlAppInfo
ctrlAppInfo :: CtrlAppInfo, ChatResponse -> AppVersion
appVersion :: AppVersion}
  | CRRemoteCtrlConnected {ChatResponse -> RemoteCtrlInfo
remoteCtrl :: RemoteCtrlInfo}
  | CRSQLResult {ChatResponse -> [Text]
rows :: [Text]}
#if !defined(dbPostgres)
  | CRArchiveExported {ChatResponse -> [ArchiveError]
archiveErrors :: [ArchiveError]}
  | CRArchiveImported {archiveErrors :: [ArchiveError]}
  | CRSlowSQLQueries {ChatResponse -> [SlowSQLQuery]
chatQueries :: [SlowSQLQuery], ChatResponse -> [SlowSQLQuery]
agentQueries :: [SlowSQLQuery]}
#endif
  | CRDebugLocks {ChatResponse -> Maybe Text
chatLockName :: Maybe Text, ChatResponse -> Map Text Text
chatEntityLocks :: Map Text Text, ChatResponse -> AgentLocks
agentLocks :: AgentLocks}
  | CRAgentSubsTotal {user :: User, ChatResponse -> SMPServerSubs
subsTotal :: SMPServerSubs, ChatResponse -> Bool
hasSession :: Bool}
  | CRAgentServersSummary {user :: User, ChatResponse -> PresentedServersSummary
serversSummary :: PresentedServersSummary}
  | CRAgentWorkersDetails {ChatResponse -> AgentWorkersDetails
agentWorkersDetails :: AgentWorkersDetails}
  | CRAgentWorkersSummary {ChatResponse -> AgentWorkersSummary
agentWorkersSummary :: AgentWorkersSummary}
  | CRAgentSubs {ChatResponse -> Map Text Int
activeSubs :: Map Text Int, ChatResponse -> Map Text Int
pendingSubs :: Map Text Int, ChatResponse -> Map Text [[Char]]
removedSubs :: Map Text [String]}
  | CRAgentSubsDetails {ChatResponse -> SubscriptionsInfo
agentSubs :: SubscriptionsInfo}
  | CRAgentQueuesInfo {ChatResponse -> AgentQueuesInfo
agentQueuesInfo :: AgentQueuesInfo}
  | CRAppSettings {ChatResponse -> AppSettings
appSettings :: AppSettings}
  | CRCustomChatResponse {user_ :: Maybe User, ChatResponse -> Text
response :: Text}
  deriving (Int -> ChatResponse -> [Char] -> [Char]
[ChatResponse] -> [Char] -> [Char]
ChatResponse -> [Char]
(Int -> ChatResponse -> [Char] -> [Char])
-> (ChatResponse -> [Char])
-> ([ChatResponse] -> [Char] -> [Char])
-> Show ChatResponse
forall a.
(Int -> a -> [Char] -> [Char])
-> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
$cshowsPrec :: Int -> ChatResponse -> [Char] -> [Char]
showsPrec :: Int -> ChatResponse -> [Char] -> [Char]
$cshow :: ChatResponse -> [Char]
show :: ChatResponse -> [Char]
$cshowList :: [ChatResponse] -> [Char] -> [Char]
showList :: [ChatResponse] -> [Char] -> [Char]
Show)

data ChatEvent
  = CEvtChatSuspended
  | CEvtContactSwitch {ChatEvent -> User
user :: User, ChatEvent -> Contact
contact :: Contact, ChatEvent -> SwitchProgress
switchProgress :: SwitchProgress}
  | CEvtGroupMemberSwitch {user :: User, ChatEvent -> GroupInfo
groupInfo :: GroupInfo, ChatEvent -> GroupMember
member :: GroupMember, switchProgress :: SwitchProgress}
  | CEvtContactRatchetSync {user :: User, contact :: Contact, ChatEvent -> RatchetSyncProgress
ratchetSyncProgress :: RatchetSyncProgress}
  | CEvtGroupMemberRatchetSync {user :: User, groupInfo :: GroupInfo, member :: GroupMember, ratchetSyncProgress :: RatchetSyncProgress}
  | CEvtChatInfoUpdated {user :: User, ChatEvent -> AChatInfo
chatInfo :: AChatInfo}
  | CEvtNewChatItems {user :: User, ChatEvent -> [AChatItem]
chatItems :: [AChatItem]} -- there is the same command response
  | CEvtChatItemsStatusesUpdated {user :: User, chatItems :: [AChatItem]}
  | CEvtChatItemUpdated {user :: User, ChatEvent -> AChatItem
chatItem :: AChatItem} -- there is the same command response
  | CEvtChatItemNotChanged {user :: User, chatItem :: AChatItem} -- there is the same command response
  | CEvtChatItemReaction {user :: User, ChatEvent -> Bool
added :: Bool, ChatEvent -> ACIReaction
reaction :: ACIReaction} -- there is the same command response
  | CEvtGroupChatItemsDeleted {user :: User, groupInfo :: GroupInfo, ChatEvent -> [Int64]
chatItemIDs :: [ChatItemId], ChatEvent -> Bool
byUser :: Bool, ChatEvent -> Maybe GroupMember
member_ :: Maybe GroupMember} -- there is the same command response
  | CEvtChatItemsDeleted {user :: User, ChatEvent -> [ChatItemDeletion]
chatItemDeletions :: [ChatItemDeletion], byUser :: Bool, ChatEvent -> Bool
timed :: Bool} -- there is the same command response
  | CEvtChatItemDeletedNotFound {user :: User, contact :: Contact, ChatEvent -> SharedMsgId
sharedMsgId :: SharedMsgId}
  | CEvtUserAcceptedGroupSent {user :: User, groupInfo :: GroupInfo, ChatEvent -> Maybe Contact
hostContact :: Maybe Contact} -- there is the same command response
  | CEvtGroupLinkConnecting {user :: User, groupInfo :: GroupInfo, ChatEvent -> GroupMember
hostMember :: GroupMember}
  | CEvtBusinessLinkConnecting {user :: User, groupInfo :: GroupInfo, hostMember :: GroupMember, ChatEvent -> Contact
fromContact :: Contact}
  | CEvtSentGroupInvitation {user :: User, groupInfo :: GroupInfo, contact :: Contact, member :: GroupMember} -- there is the same command response
  | CEvtContactUpdated {user :: User, fromContact :: Contact, ChatEvent -> Contact
toContact :: Contact}
  | CEvtGroupMemberUpdated {user :: User, groupInfo :: GroupInfo, ChatEvent -> GroupMember
fromMember :: GroupMember, ChatEvent -> GroupMember
toMember :: GroupMember}
  | CEvtContactDeletedByContact {user :: User, contact :: Contact}
  | CEvtReceivedContactRequest {user :: User, ChatEvent -> UserContactRequest
contactRequest :: UserContactRequest, ChatEvent -> Maybe AChat
chat_ :: Maybe AChat}
  | CEvtAcceptingContactRequest {user :: User, contact :: Contact} -- there is the same command response
  | CEvtAcceptingBusinessRequest {user :: User, groupInfo :: GroupInfo}
  | CEvtContactRequestAlreadyAccepted {user :: User, contact :: Contact}
  | CEvtBusinessRequestAlreadyAccepted {user :: User, groupInfo :: GroupInfo}
  | CEvtRcvFileDescrReady {user :: User, chatItem :: AChatItem, ChatEvent -> RcvFileTransfer
rcvFileTransfer :: RcvFileTransfer, ChatEvent -> RcvFileDescr
rcvFileDescr :: RcvFileDescr}
  | CEvtRcvFileAccepted {user :: User, chatItem :: AChatItem} -- there is the same command response
  -- TODO add chatItem :: AChatItem
  | CEvtRcvFileAcceptedSndCancelled {user :: User, rcvFileTransfer :: RcvFileTransfer} -- there is the same command response
  | CEvtRcvFileStart {user :: User, chatItem :: AChatItem} -- sent by chats
  | CEvtRcvFileProgressXFTP {user :: User, ChatEvent -> Maybe AChatItem
chatItem_ :: Maybe AChatItem, ChatEvent -> Int64
receivedSize :: Int64, ChatEvent -> Int64
totalSize :: Int64, rcvFileTransfer :: RcvFileTransfer}
  | CEvtRcvFileComplete {user :: User, chatItem :: AChatItem}
  | CEvtRcvStandaloneFileComplete {user :: User, ChatEvent -> [Char]
targetPath :: FilePath, rcvFileTransfer :: RcvFileTransfer}
  | CEvtRcvFileSndCancelled {user :: User, chatItem :: AChatItem, rcvFileTransfer :: RcvFileTransfer}
  | CEvtRcvFileError {user :: User, chatItem_ :: Maybe AChatItem, ChatEvent -> AgentErrorType
agentError :: AgentErrorType, rcvFileTransfer :: RcvFileTransfer}
  | CEvtRcvFileWarning {user :: User, chatItem_ :: Maybe AChatItem, agentError :: AgentErrorType, rcvFileTransfer :: RcvFileTransfer}
  | CEvtSndFileStart {user :: User, chatItem :: AChatItem, ChatEvent -> SndFileTransfer
sndFileTransfer :: SndFileTransfer}
  | CEvtSndFileComplete {user :: User, chatItem :: AChatItem, sndFileTransfer :: SndFileTransfer}
  | CEvtSndFileRcvCancelled {user :: User, chatItem_ :: Maybe AChatItem, sndFileTransfer :: SndFileTransfer}
  | CEvtSndFileProgressXFTP {user :: User, chatItem_ :: Maybe AChatItem, ChatEvent -> FileTransferMeta
fileTransferMeta :: FileTransferMeta, ChatEvent -> Int64
sentSize :: Int64, totalSize :: Int64}
  | CEvtSndFileRedirectStartXFTP {user :: User, fileTransferMeta :: FileTransferMeta, ChatEvent -> FileTransferMeta
redirectMeta :: FileTransferMeta}
  | CEvtSndFileCompleteXFTP {user :: User, chatItem :: AChatItem, fileTransferMeta :: FileTransferMeta}
  | CEvtSndStandaloneFileComplete {user :: User, fileTransferMeta :: FileTransferMeta, ChatEvent -> [Text]
rcvURIs :: [Text]}
  | CEvtSndFileError {user :: User, chatItem_ :: Maybe AChatItem, fileTransferMeta :: FileTransferMeta, ChatEvent -> Text
errorMessage :: Text}
  | CEvtSndFileWarning {user :: User, chatItem_ :: Maybe AChatItem, fileTransferMeta :: FileTransferMeta, errorMessage :: Text}
  | CEvtContactConnecting {user :: User, contact :: Contact}
  | CEvtContactConnected {user :: User, contact :: Contact, ChatEvent -> Maybe Profile
userCustomProfile :: Maybe Profile}
  | CEvtContactSndReady {user :: User, contact :: Contact}
  | CEvtContactAnotherClient {user :: User, contact :: Contact}
  | CEvtConnectionsDiff {ChatEvent -> DatabaseDiff AgentUserId
userIds :: DatabaseDiff AgentUserId, ChatEvent -> DatabaseDiff AgentConnId
connIds :: DatabaseDiff AgentConnId}
  | CEvtSubscriptionEnd {user :: User, ChatEvent -> ConnectionEntity
connectionEntity :: ConnectionEntity}
  | CEvtSubscriptionStatus {ChatEvent -> SMPServer
server :: SMPServer, ChatEvent -> SubscriptionStatus
subscriptionStatus :: SubscriptionStatus, ChatEvent -> [AgentConnId]
connections :: [AgentConnId]}
  | CEvtHostConnected {ChatEvent -> AProtocolType
protocol :: AProtocolType, ChatEvent -> TransportHost
transportHost :: TransportHost}
  | CEvtHostDisconnected {protocol :: AProtocolType, transportHost :: TransportHost}
  | CEvtReceivedGroupInvitation {user :: User, groupInfo :: GroupInfo, contact :: Contact, ChatEvent -> GroupMemberRole
fromMemberRole :: GroupMemberRole, ChatEvent -> GroupMemberRole
memberRole :: GroupMemberRole}
  | CEvtUserJoinedGroup {user :: User, groupInfo :: GroupInfo, hostMember :: GroupMember}
  | CEvtJoinedGroupMember {user :: User, groupInfo :: GroupInfo, member :: GroupMember} -- there is the same command response
  | CEvtJoinedGroupMemberConnecting {user :: User, groupInfo :: GroupInfo, hostMember :: GroupMember, member :: GroupMember}
  | CEvtMemberAcceptedByOther {user :: User, groupInfo :: GroupInfo, ChatEvent -> GroupMember
acceptingMember :: GroupMember, member :: GroupMember}
  | CEvtMemberRole {user :: User, groupInfo :: GroupInfo, ChatEvent -> GroupMember
byMember :: GroupMember, member :: GroupMember, ChatEvent -> GroupMemberRole
fromRole :: GroupMemberRole, ChatEvent -> GroupMemberRole
toRole :: GroupMemberRole}
  | CEvtMemberBlockedForAll {user :: User, groupInfo :: GroupInfo, byMember :: GroupMember, member :: GroupMember, ChatEvent -> Bool
blocked :: Bool}
  | CEvtConnectedToGroupMember {user :: User, groupInfo :: GroupInfo, member :: GroupMember, ChatEvent -> Maybe Contact
memberContact :: Maybe Contact}
  | CEvtDeletedMember {user :: User, groupInfo :: GroupInfo, byMember :: GroupMember, ChatEvent -> GroupMember
deletedMember :: GroupMember, ChatEvent -> Bool
withMessages :: Bool}
  | CEvtDeletedMemberUser {user :: User, groupInfo :: GroupInfo, member :: GroupMember, withMessages :: Bool}
  | CEvtLeftMember {user :: User, groupInfo :: GroupInfo, member :: GroupMember}
  | CEvtUnknownMemberCreated {user :: User, groupInfo :: GroupInfo, ChatEvent -> GroupMember
forwardedByMember :: GroupMember, member :: GroupMember}
  | CEvtUnknownMemberBlocked {user :: User, groupInfo :: GroupInfo, ChatEvent -> GroupMember
blockedByMember :: GroupMember, member :: GroupMember}
  | CEvtUnknownMemberAnnounced {user :: User, groupInfo :: GroupInfo, ChatEvent -> GroupMember
announcingMember :: GroupMember, ChatEvent -> GroupMember
unknownMember :: GroupMember, ChatEvent -> GroupMember
announcedMember :: GroupMember}
  | CEvtGroupDeleted {user :: User, groupInfo :: GroupInfo, member :: GroupMember}
  | CEvtGroupUpdated {user :: User, ChatEvent -> GroupInfo
fromGroup :: GroupInfo, ChatEvent -> GroupInfo
toGroup :: GroupInfo, member_ :: Maybe GroupMember} -- there is the same command response
  | CEvtAcceptingGroupJoinRequestMember {user :: User, groupInfo :: GroupInfo, member :: GroupMember}
  | CEvtNoMemberContactCreating {user :: User, groupInfo :: GroupInfo, member :: GroupMember} -- only used in CLI
  | CEvtNewMemberContactReceivedInv {user :: User, contact :: Contact, groupInfo :: GroupInfo, member :: GroupMember}
  | CEvtContactAndMemberAssociated {user :: User, contact :: Contact, groupInfo :: GroupInfo, member :: GroupMember, ChatEvent -> Contact
updatedContact :: Contact}
  | CEvtCallInvitation {ChatEvent -> RcvCallInvitation
callInvitation :: RcvCallInvitation}
  | CEvtCallOffer {user :: User, contact :: Contact, ChatEvent -> CallType
callType :: CallType, ChatEvent -> WebRTCSession
offer :: WebRTCSession, ChatEvent -> Maybe Key
sharedKey :: Maybe C.Key, ChatEvent -> Bool
askConfirmation :: Bool}
  | CEvtCallAnswer {user :: User, contact :: Contact, ChatEvent -> WebRTCSession
answer :: WebRTCSession}
  | CEvtCallExtraInfo {user :: User, contact :: Contact, ChatEvent -> WebRTCExtraInfo
extraInfo :: WebRTCExtraInfo}
  | CEvtCallEnded {user :: User, contact :: Contact}
  | CEvtNtfMessage {user :: User, ChatEvent -> ConnectionEntity
connEntity :: ConnectionEntity, ChatEvent -> NtfMsgAckInfo
ntfMessage :: NtfMsgAckInfo}
  | CEvtRemoteHostSessionCode {ChatEvent -> Maybe RemoteHostInfo
remoteHost_ :: Maybe RemoteHostInfo, ChatEvent -> Text
sessionCode :: Text}
  | CEvtNewRemoteHost {ChatEvent -> RemoteHostInfo
remoteHost :: RemoteHostInfo}
  | CEvtRemoteHostConnected {remoteHost :: RemoteHostInfo}
  | CEvtRemoteHostStopped {ChatEvent -> Maybe Int64
remoteHostId_ :: Maybe RemoteHostId, ChatEvent -> RemoteHostSessionState
rhsState :: RemoteHostSessionState, ChatEvent -> RemoteHostStopReason
rhStopReason :: RemoteHostStopReason}
  | CEvtRemoteCtrlFound {ChatEvent -> RemoteCtrlInfo
remoteCtrl :: RemoteCtrlInfo, ChatEvent -> Maybe CtrlAppInfo
ctrlAppInfo_ :: Maybe CtrlAppInfo, ChatEvent -> AppVersion
appVersion :: AppVersion, ChatEvent -> Bool
compatible :: Bool}
  | CEvtRemoteCtrlSessionCode {ChatEvent -> Maybe RemoteCtrlInfo
remoteCtrl_ :: Maybe RemoteCtrlInfo, sessionCode :: Text}
  | CEvtRemoteCtrlStopped {ChatEvent -> RemoteCtrlSessionState
rcsState :: RemoteCtrlSessionState, ChatEvent -> RemoteCtrlStopReason
rcStopReason :: RemoteCtrlStopReason}
  | CEvtContactPQEnabled {user :: User, contact :: Contact, ChatEvent -> PQEncryption
pqEnabled :: PQEncryption}
  | CEvtContactDisabled {user :: User, contact :: Contact}
  | CEvtConnectionDisabled {connectionEntity :: ConnectionEntity}
  | CEvtConnectionInactive {connectionEntity :: ConnectionEntity, ChatEvent -> Bool
inactive :: Bool}
  | CEvtAgentRcvQueuesDeleted {ChatEvent -> NonEmpty DeletedRcvQueue
deletedRcvQueues :: NonEmpty DeletedRcvQueue}
  | CEvtAgentConnsDeleted {ChatEvent -> NonEmpty AgentConnId
agentConnIds :: NonEmpty AgentConnId}
  | CEvtAgentUserDeleted {ChatEvent -> Int64
agentUserId :: Int64}
  | CEvtMessageError {user :: User, ChatEvent -> Text
severity :: Text, errorMessage :: Text}
  | CEvtChatErrors {ChatEvent -> [ChatError]
chatErrors :: [ChatError]}
  | CEvtTimedAction {ChatEvent -> [Char]
action :: String, ChatEvent -> Int64
durationMilliseconds :: Int64}
  | CEvtTerminalEvent TerminalEvent
  | CEvtCustomChatEvent {ChatEvent -> Maybe User
user_ :: Maybe User, ChatEvent -> Text
response :: Text}
  deriving (Int -> ChatEvent -> [Char] -> [Char]
[ChatEvent] -> [Char] -> [Char]
ChatEvent -> [Char]
(Int -> ChatEvent -> [Char] -> [Char])
-> (ChatEvent -> [Char])
-> ([ChatEvent] -> [Char] -> [Char])
-> Show ChatEvent
forall a.
(Int -> a -> [Char] -> [Char])
-> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
$cshowsPrec :: Int -> ChatEvent -> [Char] -> [Char]
showsPrec :: Int -> ChatEvent -> [Char] -> [Char]
$cshow :: ChatEvent -> [Char]
show :: ChatEvent -> [Char]
$cshowList :: [ChatEvent] -> [Char] -> [Char]
showList :: [ChatEvent] -> [Char] -> [Char]
Show)

data TerminalEvent
  = TEGroupLinkRejected {TerminalEvent -> User
user :: User, TerminalEvent -> GroupInfo
groupInfo :: GroupInfo, TerminalEvent -> GroupRejectionReason
groupRejectionReason :: GroupRejectionReason}
  | TERejectingGroupJoinRequestMember {user :: User, groupInfo :: GroupInfo, TerminalEvent -> GroupMember
member :: GroupMember, groupRejectionReason :: GroupRejectionReason}
  | TENewMemberContact {user :: User, TerminalEvent -> Contact
contact :: Contact, groupInfo :: GroupInfo, member :: GroupMember}
  | TEContactVerificationReset {user :: User, contact :: Contact}
  | TEGroupMemberVerificationReset {user :: User, groupInfo :: GroupInfo, member :: GroupMember}
  deriving (Int -> TerminalEvent -> [Char] -> [Char]
[TerminalEvent] -> [Char] -> [Char]
TerminalEvent -> [Char]
(Int -> TerminalEvent -> [Char] -> [Char])
-> (TerminalEvent -> [Char])
-> ([TerminalEvent] -> [Char] -> [Char])
-> Show TerminalEvent
forall a.
(Int -> a -> [Char] -> [Char])
-> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
$cshowsPrec :: Int -> TerminalEvent -> [Char] -> [Char]
showsPrec :: Int -> TerminalEvent -> [Char] -> [Char]
$cshow :: TerminalEvent -> [Char]
show :: TerminalEvent -> [Char]
$cshowList :: [TerminalEvent] -> [Char] -> [Char]
showList :: [TerminalEvent] -> [Char] -> [Char]
Show)

data DeletedRcvQueue = DeletedRcvQueue
  { DeletedRcvQueue -> AgentConnId
agentConnId :: AgentConnId,
    DeletedRcvQueue -> SMPServer
server :: SMPServer,
    DeletedRcvQueue -> AgentQueueId
agentQueueId :: AgentQueueId,
    DeletedRcvQueue -> Maybe AgentErrorType
agentError_ :: Maybe AgentErrorType
  }
  deriving (Int -> DeletedRcvQueue -> [Char] -> [Char]
[DeletedRcvQueue] -> [Char] -> [Char]
DeletedRcvQueue -> [Char]
(Int -> DeletedRcvQueue -> [Char] -> [Char])
-> (DeletedRcvQueue -> [Char])
-> ([DeletedRcvQueue] -> [Char] -> [Char])
-> Show DeletedRcvQueue
forall a.
(Int -> a -> [Char] -> [Char])
-> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
$cshowsPrec :: Int -> DeletedRcvQueue -> [Char] -> [Char]
showsPrec :: Int -> DeletedRcvQueue -> [Char] -> [Char]
$cshow :: DeletedRcvQueue -> [Char]
show :: DeletedRcvQueue -> [Char]
$cshowList :: [DeletedRcvQueue] -> [Char] -> [Char]
showList :: [DeletedRcvQueue] -> [Char] -> [Char]
Show)

allowRemoteEvent :: ChatEvent -> Bool
allowRemoteEvent :: ChatEvent -> Bool
allowRemoteEvent = \case
  ChatEvent
CEvtChatSuspended -> Bool
False
  CEvtRemoteHostSessionCode {} -> Bool
False
  CEvtNewRemoteHost RemoteHostInfo
_ -> Bool
False
  CEvtRemoteHostConnected RemoteHostInfo
_ -> Bool
False
  CEvtRemoteHostStopped {} -> Bool
False
  CEvtRemoteCtrlFound {} -> Bool
False
  CEvtRemoteCtrlSessionCode {} -> Bool
False
  CEvtRemoteCtrlStopped {} -> Bool
False
  ChatEvent
_ -> Bool
True

logEventToFile :: ChatEvent -> Bool
logEventToFile :: ChatEvent -> Bool
logEventToFile = \case
  CEvtSubscriptionStatus {} -> Bool
True
  CEvtHostConnected {} -> Bool
True
  CEvtHostDisconnected {} -> Bool
True
  CEvtConnectionDisabled {} -> Bool
True
  CEvtAgentRcvQueuesDeleted {} -> Bool
True
  CEvtAgentConnsDeleted {} -> Bool
True
  CEvtAgentUserDeleted {} -> Bool
True
  -- CRChatCmdError {} -> True -- TODO this should be separately logged to file as command error
  CEvtMessageError {} -> Bool
True
  ChatEvent
_ -> Bool
False

data SendRef
  = SRDirect ContactId
  | SRGroup GroupId (Maybe GroupChatScope)
  deriving (SendRef -> SendRef -> Bool
(SendRef -> SendRef -> Bool)
-> (SendRef -> SendRef -> Bool) -> Eq SendRef
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: SendRef -> SendRef -> Bool
== :: SendRef -> SendRef -> Bool
$c/= :: SendRef -> SendRef -> Bool
/= :: SendRef -> SendRef -> Bool
Eq, Int -> SendRef -> [Char] -> [Char]
[SendRef] -> [Char] -> [Char]
SendRef -> [Char]
(Int -> SendRef -> [Char] -> [Char])
-> (SendRef -> [Char])
-> ([SendRef] -> [Char] -> [Char])
-> Show SendRef
forall a.
(Int -> a -> [Char] -> [Char])
-> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
$cshowsPrec :: Int -> SendRef -> [Char] -> [Char]
showsPrec :: Int -> SendRef -> [Char] -> [Char]
$cshow :: SendRef -> [Char]
show :: SendRef -> [Char]
$cshowList :: [SendRef] -> [Char] -> [Char]
showList :: [SendRef] -> [Char] -> [Char]
Show)

sendToChatRef :: SendRef -> ChatRef
sendToChatRef :: SendRef -> ChatRef
sendToChatRef = \case
  SRDirect Int64
cId -> ChatType -> Int64 -> Maybe GroupChatScope -> ChatRef
ChatRef ChatType
CTDirect Int64
cId Maybe GroupChatScope
forall a. Maybe a
Nothing
  SRGroup Int64
gId Maybe GroupChatScope
scope -> ChatType -> Int64 -> Maybe GroupChatScope -> ChatRef
ChatRef ChatType
CTGroup Int64
gId Maybe GroupChatScope
scope

data ChatPagination
  = CPLast Int
  | CPAfter ChatItemId Int
  | CPBefore ChatItemId Int
  | CPAround ChatItemId Int
  | CPInitial Int
  deriving (Int -> ChatPagination -> [Char] -> [Char]
[ChatPagination] -> [Char] -> [Char]
ChatPagination -> [Char]
(Int -> ChatPagination -> [Char] -> [Char])
-> (ChatPagination -> [Char])
-> ([ChatPagination] -> [Char] -> [Char])
-> Show ChatPagination
forall a.
(Int -> a -> [Char] -> [Char])
-> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
$cshowsPrec :: Int -> ChatPagination -> [Char] -> [Char]
showsPrec :: Int -> ChatPagination -> [Char] -> [Char]
$cshow :: ChatPagination -> [Char]
show :: ChatPagination -> [Char]
$cshowList :: [ChatPagination] -> [Char] -> [Char]
showList :: [ChatPagination] -> [Char] -> [Char]
Show)

data PaginationByTime
  = PTLast Int
  | PTAfter UTCTime Int
  | PTBefore UTCTime Int
  deriving (Int -> PaginationByTime -> [Char] -> [Char]
[PaginationByTime] -> [Char] -> [Char]
PaginationByTime -> [Char]
(Int -> PaginationByTime -> [Char] -> [Char])
-> (PaginationByTime -> [Char])
-> ([PaginationByTime] -> [Char] -> [Char])
-> Show PaginationByTime
forall a.
(Int -> a -> [Char] -> [Char])
-> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
$cshowsPrec :: Int -> PaginationByTime -> [Char] -> [Char]
showsPrec :: Int -> PaginationByTime -> [Char] -> [Char]
$cshow :: PaginationByTime -> [Char]
show :: PaginationByTime -> [Char]
$cshowList :: [PaginationByTime] -> [Char] -> [Char]
showList :: [PaginationByTime] -> [Char] -> [Char]
Show)

data ChatListQuery
  = CLQFilters {ChatListQuery -> Bool
favorite :: Bool, ChatListQuery -> Bool
unread :: Bool}
  | CLQSearch {ChatListQuery -> [Char]
search :: String}
  deriving (Int -> ChatListQuery -> [Char] -> [Char]
[ChatListQuery] -> [Char] -> [Char]
ChatListQuery -> [Char]
(Int -> ChatListQuery -> [Char] -> [Char])
-> (ChatListQuery -> [Char])
-> ([ChatListQuery] -> [Char] -> [Char])
-> Show ChatListQuery
forall a.
(Int -> a -> [Char] -> [Char])
-> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
$cshowsPrec :: Int -> ChatListQuery -> [Char] -> [Char]
showsPrec :: Int -> ChatListQuery -> [Char] -> [Char]
$cshow :: ChatListQuery -> [Char]
show :: ChatListQuery -> [Char]
$cshowList :: [ChatListQuery] -> [Char] -> [Char]
showList :: [ChatListQuery] -> [Char] -> [Char]
Show)

clqNoFilters :: ChatListQuery
clqNoFilters :: ChatListQuery
clqNoFilters = CLQFilters {favorite :: Bool
favorite = Bool
False, unread :: Bool
unread = Bool
False}

data ChatDeleteMode
  = CDMFull {ChatDeleteMode -> Bool
notify :: Bool} -- delete both contact and conversation
  | CDMEntity {notify :: Bool} -- delete contact (connection), keep conversation
  | CDMMessages -- delete conversation, keep contact - can be re-opened from Contacts view
  deriving (Int -> ChatDeleteMode -> [Char] -> [Char]
[ChatDeleteMode] -> [Char] -> [Char]
ChatDeleteMode -> [Char]
(Int -> ChatDeleteMode -> [Char] -> [Char])
-> (ChatDeleteMode -> [Char])
-> ([ChatDeleteMode] -> [Char] -> [Char])
-> Show ChatDeleteMode
forall a.
(Int -> a -> [Char] -> [Char])
-> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
$cshowsPrec :: Int -> ChatDeleteMode -> [Char] -> [Char]
showsPrec :: Int -> ChatDeleteMode -> [Char] -> [Char]
$cshow :: ChatDeleteMode -> [Char]
show :: ChatDeleteMode -> [Char]
$cshowList :: [ChatDeleteMode] -> [Char] -> [Char]
showList :: [ChatDeleteMode] -> [Char] -> [Char]
Show)

data ConnectionPlan
  = CPInvitationLink {ConnectionPlan -> InvitationLinkPlan
invitationLinkPlan :: InvitationLinkPlan}
  | CPContactAddress {ConnectionPlan -> ContactAddressPlan
contactAddressPlan :: ContactAddressPlan}
  | CPGroupLink {ConnectionPlan -> GroupLinkPlan
groupLinkPlan :: GroupLinkPlan}
  | CPError {ConnectionPlan -> ChatError
chatError :: ChatError}
  deriving (Int -> ConnectionPlan -> [Char] -> [Char]
[ConnectionPlan] -> [Char] -> [Char]
ConnectionPlan -> [Char]
(Int -> ConnectionPlan -> [Char] -> [Char])
-> (ConnectionPlan -> [Char])
-> ([ConnectionPlan] -> [Char] -> [Char])
-> Show ConnectionPlan
forall a.
(Int -> a -> [Char] -> [Char])
-> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
$cshowsPrec :: Int -> ConnectionPlan -> [Char] -> [Char]
showsPrec :: Int -> ConnectionPlan -> [Char] -> [Char]
$cshow :: ConnectionPlan -> [Char]
show :: ConnectionPlan -> [Char]
$cshowList :: [ConnectionPlan] -> [Char] -> [Char]
showList :: [ConnectionPlan] -> [Char] -> [Char]
Show)

data InvitationLinkPlan
  = ILPOk {InvitationLinkPlan -> Maybe ContactShortLinkData
contactSLinkData_ :: Maybe ContactShortLinkData}
  | ILPOwnLink
  | ILPConnecting {InvitationLinkPlan -> Maybe Contact
contact_ :: Maybe Contact}
  | ILPKnown {InvitationLinkPlan -> Contact
contact :: Contact}
  deriving (Int -> InvitationLinkPlan -> [Char] -> [Char]
[InvitationLinkPlan] -> [Char] -> [Char]
InvitationLinkPlan -> [Char]
(Int -> InvitationLinkPlan -> [Char] -> [Char])
-> (InvitationLinkPlan -> [Char])
-> ([InvitationLinkPlan] -> [Char] -> [Char])
-> Show InvitationLinkPlan
forall a.
(Int -> a -> [Char] -> [Char])
-> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
$cshowsPrec :: Int -> InvitationLinkPlan -> [Char] -> [Char]
showsPrec :: Int -> InvitationLinkPlan -> [Char] -> [Char]
$cshow :: InvitationLinkPlan -> [Char]
show :: InvitationLinkPlan -> [Char]
$cshowList :: [InvitationLinkPlan] -> [Char] -> [Char]
showList :: [InvitationLinkPlan] -> [Char] -> [Char]
Show)

data ContactAddressPlan
  = CAPOk {ContactAddressPlan -> Maybe ContactShortLinkData
contactSLinkData_ :: Maybe ContactShortLinkData}
  | CAPOwnLink
  | CAPConnectingConfirmReconnect
  | CAPConnectingProhibit {ContactAddressPlan -> Contact
contact :: Contact}
  | CAPKnown {contact :: Contact}
  | CAPContactViaAddress {contact :: Contact}
  deriving (Int -> ContactAddressPlan -> [Char] -> [Char]
[ContactAddressPlan] -> [Char] -> [Char]
ContactAddressPlan -> [Char]
(Int -> ContactAddressPlan -> [Char] -> [Char])
-> (ContactAddressPlan -> [Char])
-> ([ContactAddressPlan] -> [Char] -> [Char])
-> Show ContactAddressPlan
forall a.
(Int -> a -> [Char] -> [Char])
-> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
$cshowsPrec :: Int -> ContactAddressPlan -> [Char] -> [Char]
showsPrec :: Int -> ContactAddressPlan -> [Char] -> [Char]
$cshow :: ContactAddressPlan -> [Char]
show :: ContactAddressPlan -> [Char]
$cshowList :: [ContactAddressPlan] -> [Char] -> [Char]
showList :: [ContactAddressPlan] -> [Char] -> [Char]
Show)

data GroupLinkPlan
  = GLPOk {GroupLinkPlan -> Maybe GroupShortLinkData
groupSLinkData_ :: Maybe GroupShortLinkData}
  | GLPOwnLink {GroupLinkPlan -> GroupInfo
groupInfo :: GroupInfo}
  | GLPConnectingConfirmReconnect
  | GLPConnectingProhibit {GroupLinkPlan -> Maybe GroupInfo
groupInfo_ :: Maybe GroupInfo}
  | GLPKnown {groupInfo :: GroupInfo}
  deriving (Int -> GroupLinkPlan -> [Char] -> [Char]
[GroupLinkPlan] -> [Char] -> [Char]
GroupLinkPlan -> [Char]
(Int -> GroupLinkPlan -> [Char] -> [Char])
-> (GroupLinkPlan -> [Char])
-> ([GroupLinkPlan] -> [Char] -> [Char])
-> Show GroupLinkPlan
forall a.
(Int -> a -> [Char] -> [Char])
-> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
$cshowsPrec :: Int -> GroupLinkPlan -> [Char] -> [Char]
showsPrec :: Int -> GroupLinkPlan -> [Char] -> [Char]
$cshow :: GroupLinkPlan -> [Char]
show :: GroupLinkPlan -> [Char]
$cshowList :: [GroupLinkPlan] -> [Char] -> [Char]
showList :: [GroupLinkPlan] -> [Char] -> [Char]
Show)

connectionPlanProceed :: ConnectionPlan -> Bool
connectionPlanProceed :: ConnectionPlan -> Bool
connectionPlanProceed = \case
  CPInvitationLink InvitationLinkPlan
ilp -> case InvitationLinkPlan
ilp of
    ILPOk Maybe ContactShortLinkData
_ -> Bool
True
    InvitationLinkPlan
ILPOwnLink -> Bool
True
    InvitationLinkPlan
_ -> Bool
False
  CPContactAddress ContactAddressPlan
cap -> case ContactAddressPlan
cap of
    CAPOk Maybe ContactShortLinkData
_ -> Bool
True
    ContactAddressPlan
CAPOwnLink -> Bool
True
    ContactAddressPlan
CAPConnectingConfirmReconnect -> Bool
True
    CAPContactViaAddress Contact
_ -> Bool
True
    ContactAddressPlan
_ -> Bool
False
  CPGroupLink GroupLinkPlan
glp -> case GroupLinkPlan
glp of
    GLPOk Maybe GroupShortLinkData
_ -> Bool
True
    GLPOwnLink GroupInfo
_ -> Bool
True
    GroupLinkPlan
GLPConnectingConfirmReconnect -> Bool
True
    GroupLinkPlan
_ -> Bool
False
  CPError ChatError
_ -> Bool
True

data ForwardConfirmation
  = FCFilesNotAccepted {ForwardConfirmation -> [Int64]
fileIds :: [FileTransferId]}
  | FCFilesInProgress {ForwardConfirmation -> Int
filesCount :: Int}
  | FCFilesMissing {filesCount :: Int}
  | FCFilesFailed {filesCount :: Int}
  deriving (Int -> ForwardConfirmation -> [Char] -> [Char]
[ForwardConfirmation] -> [Char] -> [Char]
ForwardConfirmation -> [Char]
(Int -> ForwardConfirmation -> [Char] -> [Char])
-> (ForwardConfirmation -> [Char])
-> ([ForwardConfirmation] -> [Char] -> [Char])
-> Show ForwardConfirmation
forall a.
(Int -> a -> [Char] -> [Char])
-> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
$cshowsPrec :: Int -> ForwardConfirmation -> [Char] -> [Char]
showsPrec :: Int -> ForwardConfirmation -> [Char] -> [Char]
$cshow :: ForwardConfirmation -> [Char]
show :: ForwardConfirmation -> [Char]
$cshowList :: [ForwardConfirmation] -> [Char] -> [Char]
showList :: [ForwardConfirmation] -> [Char] -> [Char]
Show)

newtype UserPwd = UserPwd {UserPwd -> Text
unUserPwd :: Text}
  deriving (UserPwd -> UserPwd -> Bool
(UserPwd -> UserPwd -> Bool)
-> (UserPwd -> UserPwd -> Bool) -> Eq UserPwd
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: UserPwd -> UserPwd -> Bool
== :: UserPwd -> UserPwd -> Bool
$c/= :: UserPwd -> UserPwd -> Bool
/= :: UserPwd -> UserPwd -> Bool
Eq, Int -> UserPwd -> [Char] -> [Char]
[UserPwd] -> [Char] -> [Char]
UserPwd -> [Char]
(Int -> UserPwd -> [Char] -> [Char])
-> (UserPwd -> [Char])
-> ([UserPwd] -> [Char] -> [Char])
-> Show UserPwd
forall a.
(Int -> a -> [Char] -> [Char])
-> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
$cshowsPrec :: Int -> UserPwd -> [Char] -> [Char]
showsPrec :: Int -> UserPwd -> [Char] -> [Char]
$cshow :: UserPwd -> [Char]
show :: UserPwd -> [Char]
$cshowList :: [UserPwd] -> [Char] -> [Char]
showList :: [UserPwd] -> [Char] -> [Char]
Show)

instance FromJSON UserPwd where
  parseJSON :: Value -> Parser UserPwd
parseJSON Value
v = Text -> UserPwd
UserPwd (Text -> UserPwd) -> Parser Text -> Parser UserPwd
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Value -> Parser Text
forall a. FromJSON a => Value -> Parser a
parseJSON Value
v

instance ToJSON UserPwd where
  toJSON :: UserPwd -> Value
toJSON (UserPwd Text
p) = Text -> Value
forall a. ToJSON a => a -> Value
toJSON Text
p
  toEncoding :: UserPwd -> Encoding
toEncoding (UserPwd Text
p) = Text -> Encoding
forall a. ToJSON a => a -> Encoding
toEncoding Text
p

newtype AgentQueueId = AgentQueueId QueueId
  deriving (AgentQueueId -> AgentQueueId -> Bool
(AgentQueueId -> AgentQueueId -> Bool)
-> (AgentQueueId -> AgentQueueId -> Bool) -> Eq AgentQueueId
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: AgentQueueId -> AgentQueueId -> Bool
== :: AgentQueueId -> AgentQueueId -> Bool
$c/= :: AgentQueueId -> AgentQueueId -> Bool
/= :: AgentQueueId -> AgentQueueId -> Bool
Eq, Int -> AgentQueueId -> [Char] -> [Char]
[AgentQueueId] -> [Char] -> [Char]
AgentQueueId -> [Char]
(Int -> AgentQueueId -> [Char] -> [Char])
-> (AgentQueueId -> [Char])
-> ([AgentQueueId] -> [Char] -> [Char])
-> Show AgentQueueId
forall a.
(Int -> a -> [Char] -> [Char])
-> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
$cshowsPrec :: Int -> AgentQueueId -> [Char] -> [Char]
showsPrec :: Int -> AgentQueueId -> [Char] -> [Char]
$cshow :: AgentQueueId -> [Char]
show :: AgentQueueId -> [Char]
$cshowList :: [AgentQueueId] -> [Char] -> [Char]
showList :: [AgentQueueId] -> [Char] -> [Char]
Show)

instance StrEncoding AgentQueueId where
  strEncode :: AgentQueueId -> MsgId
strEncode (AgentQueueId QueueId
qId) = QueueId -> MsgId
forall a. StrEncoding a => a -> MsgId
strEncode QueueId
qId
  strDecode :: MsgId -> Either [Char] AgentQueueId
strDecode MsgId
s = QueueId -> AgentQueueId
AgentQueueId (QueueId -> AgentQueueId)
-> Either [Char] QueueId -> Either [Char] AgentQueueId
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> MsgId -> Either [Char] QueueId
forall a. StrEncoding a => MsgId -> Either [Char] a
strDecode MsgId
s
  strP :: Parser AgentQueueId
strP = QueueId -> AgentQueueId
AgentQueueId (QueueId -> AgentQueueId)
-> Parser MsgId QueueId -> Parser AgentQueueId
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser MsgId QueueId
forall a. StrEncoding a => Parser a
strP

instance FromJSON AgentQueueId where
  parseJSON :: Value -> Parser AgentQueueId
parseJSON = [Char] -> Value -> Parser AgentQueueId
forall a. StrEncoding a => [Char] -> Value -> Parser a
strParseJSON [Char]
"AgentQueueId"

instance ToJSON AgentQueueId where
  toJSON :: AgentQueueId -> Value
toJSON = AgentQueueId -> Value
forall a. StrEncoding a => a -> Value
strToJSON
  toEncoding :: AgentQueueId -> Encoding
toEncoding = AgentQueueId -> Encoding
forall a. StrEncoding a => a -> Encoding
strToJEncoding

data ArchiveConfig = ArchiveConfig {ArchiveConfig -> [Char]
archivePath :: FilePath, ArchiveConfig -> Maybe Bool
disableCompression :: Maybe Bool, ArchiveConfig -> Maybe [Char]
parentTempDirectory :: Maybe FilePath}
  deriving (Int -> ArchiveConfig -> [Char] -> [Char]
[ArchiveConfig] -> [Char] -> [Char]
ArchiveConfig -> [Char]
(Int -> ArchiveConfig -> [Char] -> [Char])
-> (ArchiveConfig -> [Char])
-> ([ArchiveConfig] -> [Char] -> [Char])
-> Show ArchiveConfig
forall a.
(Int -> a -> [Char] -> [Char])
-> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
$cshowsPrec :: Int -> ArchiveConfig -> [Char] -> [Char]
showsPrec :: Int -> ArchiveConfig -> [Char] -> [Char]
$cshow :: ArchiveConfig -> [Char]
show :: ArchiveConfig -> [Char]
$cshowList :: [ArchiveConfig] -> [Char] -> [Char]
showList :: [ArchiveConfig] -> [Char] -> [Char]
Show)

data DBEncryptionConfig = DBEncryptionConfig {DBEncryptionConfig -> DBEncryptionKey
currentKey :: DBEncryptionKey, DBEncryptionConfig -> DBEncryptionKey
newKey :: DBEncryptionKey, DBEncryptionConfig -> Maybe Bool
keepKey :: Maybe Bool}
  deriving (Int -> DBEncryptionConfig -> [Char] -> [Char]
[DBEncryptionConfig] -> [Char] -> [Char]
DBEncryptionConfig -> [Char]
(Int -> DBEncryptionConfig -> [Char] -> [Char])
-> (DBEncryptionConfig -> [Char])
-> ([DBEncryptionConfig] -> [Char] -> [Char])
-> Show DBEncryptionConfig
forall a.
(Int -> a -> [Char] -> [Char])
-> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
$cshowsPrec :: Int -> DBEncryptionConfig -> [Char] -> [Char]
showsPrec :: Int -> DBEncryptionConfig -> [Char] -> [Char]
$cshow :: DBEncryptionConfig -> [Char]
show :: DBEncryptionConfig -> [Char]
$cshowList :: [DBEncryptionConfig] -> [Char] -> [Char]
showList :: [DBEncryptionConfig] -> [Char] -> [Char]
Show)

newtype DBEncryptionKey = DBEncryptionKey ScrubbedBytes
  deriving (Int -> DBEncryptionKey -> [Char] -> [Char]
[DBEncryptionKey] -> [Char] -> [Char]
DBEncryptionKey -> [Char]
(Int -> DBEncryptionKey -> [Char] -> [Char])
-> (DBEncryptionKey -> [Char])
-> ([DBEncryptionKey] -> [Char] -> [Char])
-> Show DBEncryptionKey
forall a.
(Int -> a -> [Char] -> [Char])
-> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
$cshowsPrec :: Int -> DBEncryptionKey -> [Char] -> [Char]
showsPrec :: Int -> DBEncryptionKey -> [Char] -> [Char]
$cshow :: DBEncryptionKey -> [Char]
show :: DBEncryptionKey -> [Char]
$cshowList :: [DBEncryptionKey] -> [Char] -> [Char]
showList :: [DBEncryptionKey] -> [Char] -> [Char]
Show)

instance IsString DBEncryptionKey where fromString :: [Char] -> DBEncryptionKey
fromString = (MsgId -> Either [Char] DBEncryptionKey)
-> [Char] -> DBEncryptionKey
forall a. (MsgId -> Either [Char] a) -> [Char] -> a
parseString ((MsgId -> Either [Char] DBEncryptionKey)
 -> [Char] -> DBEncryptionKey)
-> (MsgId -> Either [Char] DBEncryptionKey)
-> [Char]
-> DBEncryptionKey
forall a b. (a -> b) -> a -> b
$ Parser DBEncryptionKey -> MsgId -> Either [Char] DBEncryptionKey
forall a. Parser a -> MsgId -> Either [Char] a
parseAll Parser DBEncryptionKey
forall a. StrEncoding a => Parser a
strP

instance StrEncoding DBEncryptionKey where
  strEncode :: DBEncryptionKey -> MsgId
strEncode (DBEncryptionKey ScrubbedBytes
s) = ScrubbedBytes -> MsgId
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
BA.convert ScrubbedBytes
s
  strP :: Parser DBEncryptionKey
strP = ScrubbedBytes -> DBEncryptionKey
DBEncryptionKey (ScrubbedBytes -> DBEncryptionKey)
-> (MsgId -> ScrubbedBytes) -> MsgId -> DBEncryptionKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MsgId -> ScrubbedBytes
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
BA.convert (MsgId -> DBEncryptionKey)
-> Parser MsgId MsgId -> Parser DBEncryptionKey
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Char -> Bool) -> Parser MsgId MsgId
A.takeWhile (\Char
c -> Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= Char
' ' Bool -> Bool -> Bool
&& Char -> Int
ord Char
c Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0x21 Bool -> Bool -> Bool
&& Char -> Int
ord Char
c Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0x7E)

instance FromJSON DBEncryptionKey where
  parseJSON :: Value -> Parser DBEncryptionKey
parseJSON = [Char] -> Value -> Parser DBEncryptionKey
forall a. StrEncoding a => [Char] -> Value -> Parser a
strParseJSON [Char]
"DBEncryptionKey"

data AppFilePathsConfig = AppFilePathsConfig
  { AppFilePathsConfig -> [Char]
appFilesFolder :: FilePath,
    AppFilePathsConfig -> [Char]
appTempFolder :: FilePath,
    AppFilePathsConfig -> [Char]
appAssetsFolder :: FilePath,
    AppFilePathsConfig -> Maybe [Char]
appRemoteHostsFolder :: Maybe FilePath
  }
  deriving (Int -> AppFilePathsConfig -> [Char] -> [Char]
[AppFilePathsConfig] -> [Char] -> [Char]
AppFilePathsConfig -> [Char]
(Int -> AppFilePathsConfig -> [Char] -> [Char])
-> (AppFilePathsConfig -> [Char])
-> ([AppFilePathsConfig] -> [Char] -> [Char])
-> Show AppFilePathsConfig
forall a.
(Int -> a -> [Char] -> [Char])
-> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
$cshowsPrec :: Int -> AppFilePathsConfig -> [Char] -> [Char]
showsPrec :: Int -> AppFilePathsConfig -> [Char] -> [Char]
$cshow :: AppFilePathsConfig -> [Char]
show :: AppFilePathsConfig -> [Char]
$cshowList :: [AppFilePathsConfig] -> [Char] -> [Char]
showList :: [AppFilePathsConfig] -> [Char] -> [Char]
Show)

data SimpleNetCfg = SimpleNetCfg
  { SimpleNetCfg -> Maybe SocksProxyWithAuth
socksProxy :: Maybe SocksProxyWithAuth,
    SimpleNetCfg -> SocksMode
socksMode :: SocksMode,
    SimpleNetCfg -> HostMode
hostMode :: HostMode,
    SimpleNetCfg -> Bool
requiredHostMode :: Bool,
    SimpleNetCfg -> Maybe SMPProxyMode
smpProxyMode_ :: Maybe SMPProxyMode,
    SimpleNetCfg -> Maybe SMPProxyFallback
smpProxyFallback_ :: Maybe SMPProxyFallback,
    SimpleNetCfg -> SMPWebPortServers
smpWebPortServers :: SMPWebPortServers,
    SimpleNetCfg -> Maybe Int
tcpTimeout_ :: Maybe Int,
    SimpleNetCfg -> Bool
logTLSErrors :: Bool
  }
  deriving (Int -> SimpleNetCfg -> [Char] -> [Char]
[SimpleNetCfg] -> [Char] -> [Char]
SimpleNetCfg -> [Char]
(Int -> SimpleNetCfg -> [Char] -> [Char])
-> (SimpleNetCfg -> [Char])
-> ([SimpleNetCfg] -> [Char] -> [Char])
-> Show SimpleNetCfg
forall a.
(Int -> a -> [Char] -> [Char])
-> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
$cshowsPrec :: Int -> SimpleNetCfg -> [Char] -> [Char]
showsPrec :: Int -> SimpleNetCfg -> [Char] -> [Char]
$cshow :: SimpleNetCfg -> [Char]
show :: SimpleNetCfg -> [Char]
$cshowList :: [SimpleNetCfg] -> [Char] -> [Char]
showList :: [SimpleNetCfg] -> [Char] -> [Char]
Show)

defaultSimpleNetCfg :: SimpleNetCfg
defaultSimpleNetCfg :: SimpleNetCfg
defaultSimpleNetCfg =
  SimpleNetCfg
    { socksProxy :: Maybe SocksProxyWithAuth
socksProxy = Maybe SocksProxyWithAuth
forall a. Maybe a
Nothing,
      socksMode :: SocksMode
socksMode = SocksMode
SMAlways,
      hostMode :: HostMode
hostMode = HostMode
HMOnionViaSocks,
      requiredHostMode :: Bool
requiredHostMode = Bool
False,
      smpProxyMode_ :: Maybe SMPProxyMode
smpProxyMode_ = Maybe SMPProxyMode
forall a. Maybe a
Nothing,
      smpProxyFallback_ :: Maybe SMPProxyFallback
smpProxyFallback_ = Maybe SMPProxyFallback
forall a. Maybe a
Nothing,
      smpWebPortServers :: SMPWebPortServers
smpWebPortServers = SMPWebPortServers
SWPPreset,
      tcpTimeout_ :: Maybe Int
tcpTimeout_ = Maybe Int
forall a. Maybe a
Nothing,
      logTLSErrors :: Bool
logTLSErrors = Bool
False
    }

data ConnSubResult = ConnSubResult
  { ConnSubResult -> AgentConnId
agentConnId :: AgentConnId,
    ConnSubResult -> Maybe ChatError
connSubError :: Maybe ChatError
  }
  deriving (Int -> ConnSubResult -> [Char] -> [Char]
[ConnSubResult] -> [Char] -> [Char]
ConnSubResult -> [Char]
(Int -> ConnSubResult -> [Char] -> [Char])
-> (ConnSubResult -> [Char])
-> ([ConnSubResult] -> [Char] -> [Char])
-> Show ConnSubResult
forall a.
(Int -> a -> [Char] -> [Char])
-> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
$cshowsPrec :: Int -> ConnSubResult -> [Char] -> [Char]
showsPrec :: Int -> ConnSubResult -> [Char] -> [Char]
$cshow :: ConnSubResult -> [Char]
show :: ConnSubResult -> [Char]
$cshowList :: [ConnSubResult] -> [Char] -> [Char]
showList :: [ConnSubResult] -> [Char] -> [Char]
Show)

data UserProfileUpdateSummary = UserProfileUpdateSummary
  { UserProfileUpdateSummary -> Int
updateSuccesses :: Int,
    UserProfileUpdateSummary -> Int
updateFailures :: Int,
    UserProfileUpdateSummary -> [Contact]
changedContacts :: [Contact]
  }
  deriving (Int -> UserProfileUpdateSummary -> [Char] -> [Char]
[UserProfileUpdateSummary] -> [Char] -> [Char]
UserProfileUpdateSummary -> [Char]
(Int -> UserProfileUpdateSummary -> [Char] -> [Char])
-> (UserProfileUpdateSummary -> [Char])
-> ([UserProfileUpdateSummary] -> [Char] -> [Char])
-> Show UserProfileUpdateSummary
forall a.
(Int -> a -> [Char] -> [Char])
-> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
$cshowsPrec :: Int -> UserProfileUpdateSummary -> [Char] -> [Char]
showsPrec :: Int -> UserProfileUpdateSummary -> [Char] -> [Char]
$cshow :: UserProfileUpdateSummary -> [Char]
show :: UserProfileUpdateSummary -> [Char]
$cshowList :: [UserProfileUpdateSummary] -> [Char] -> [Char]
showList :: [UserProfileUpdateSummary] -> [Char] -> [Char]
Show)

data ComposedMessage = ComposedMessage
  { ComposedMessage -> Maybe CryptoFile
fileSource :: Maybe CryptoFile,
    ComposedMessage -> Maybe Int64
quotedItemId :: Maybe ChatItemId,
    ComposedMessage -> MsgContent
msgContent :: MsgContent,
    ComposedMessage -> Map Text Int64
mentions :: Map MemberName GroupMemberId
  }
  deriving (Int -> ComposedMessage -> [Char] -> [Char]
[ComposedMessage] -> [Char] -> [Char]
ComposedMessage -> [Char]
(Int -> ComposedMessage -> [Char] -> [Char])
-> (ComposedMessage -> [Char])
-> ([ComposedMessage] -> [Char] -> [Char])
-> Show ComposedMessage
forall a.
(Int -> a -> [Char] -> [Char])
-> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
$cshowsPrec :: Int -> ComposedMessage -> [Char] -> [Char]
showsPrec :: Int -> ComposedMessage -> [Char] -> [Char]
$cshow :: ComposedMessage -> [Char]
show :: ComposedMessage -> [Char]
$cshowList :: [ComposedMessage] -> [Char] -> [Char]
showList :: [ComposedMessage] -> [Char] -> [Char]
Show)

data UpdatedMessage = UpdatedMessage
  { UpdatedMessage -> MsgContent
msgContent :: MsgContent,
    UpdatedMessage -> Map Text Int64
mentions :: Map MemberName GroupMemberId
  }
  deriving (Int -> UpdatedMessage -> [Char] -> [Char]
[UpdatedMessage] -> [Char] -> [Char]
UpdatedMessage -> [Char]
(Int -> UpdatedMessage -> [Char] -> [Char])
-> (UpdatedMessage -> [Char])
-> ([UpdatedMessage] -> [Char] -> [Char])
-> Show UpdatedMessage
forall a.
(Int -> a -> [Char] -> [Char])
-> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
$cshowsPrec :: Int -> UpdatedMessage -> [Char] -> [Char]
showsPrec :: Int -> UpdatedMessage -> [Char] -> [Char]
$cshow :: UpdatedMessage -> [Char]
show :: UpdatedMessage -> [Char]
$cshowList :: [UpdatedMessage] -> [Char] -> [Char]
showList :: [UpdatedMessage] -> [Char] -> [Char]
Show)

data ChatTagData = ChatTagData
  { ChatTagData -> Maybe Text
emoji :: Maybe Text,
    ChatTagData -> Text
text :: Text
  }
  deriving (Int -> ChatTagData -> [Char] -> [Char]
[ChatTagData] -> [Char] -> [Char]
ChatTagData -> [Char]
(Int -> ChatTagData -> [Char] -> [Char])
-> (ChatTagData -> [Char])
-> ([ChatTagData] -> [Char] -> [Char])
-> Show ChatTagData
forall a.
(Int -> a -> [Char] -> [Char])
-> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
$cshowsPrec :: Int -> ChatTagData -> [Char] -> [Char]
showsPrec :: Int -> ChatTagData -> [Char] -> [Char]
$cshow :: ChatTagData -> [Char]
show :: ChatTagData -> [Char]
$cshowList :: [ChatTagData] -> [Char] -> [Char]
showList :: [ChatTagData] -> [Char] -> [Char]
Show)

instance FromJSON ChatTagData where
  parseJSON :: Value -> Parser ChatTagData
parseJSON (J.Object Object
v) = Maybe Text -> Text -> ChatTagData
ChatTagData (Maybe Text -> Text -> ChatTagData)
-> Parser (Maybe Text) -> Parser (Text -> ChatTagData)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
v Object -> Key -> Parser (Maybe Text)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"emoji" Parser (Text -> ChatTagData) -> Parser Text -> Parser ChatTagData
forall a b. Parser (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Object
v Object -> Key -> Parser Text
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"text"
  parseJSON Value
invalid = [Char] -> Parser ChatTagData -> Parser ChatTagData
forall a. [Char] -> Parser a -> Parser a
JT.prependFailure [Char]
"bad ChatTagData, " ([Char] -> Value -> Parser ChatTagData
forall a. [Char] -> Value -> Parser a
JT.typeMismatch [Char]
"Object" Value
invalid)

data NtfConn = NtfConn
  { NtfConn -> User
user :: User,
    NtfConn -> AgentConnId
agentConnId :: AgentConnId,
    NtfConn -> Int64
agentDbQueueId :: Int64,
    NtfConn -> ConnectionEntity
connEntity :: ConnectionEntity,
    -- Decrypted ntf meta of the expected message (the one notification was sent for).
    -- Nothing means it failed to decrypt or to decode, we can still show event for entity
    NtfConn -> Maybe NtfMsgInfo
expectedMsg_ :: Maybe NtfMsgInfo
  }
  deriving (Int -> NtfConn -> [Char] -> [Char]
[NtfConn] -> [Char] -> [Char]
NtfConn -> [Char]
(Int -> NtfConn -> [Char] -> [Char])
-> (NtfConn -> [Char])
-> ([NtfConn] -> [Char] -> [Char])
-> Show NtfConn
forall a.
(Int -> a -> [Char] -> [Char])
-> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
$cshowsPrec :: Int -> NtfConn -> [Char] -> [Char]
showsPrec :: Int -> NtfConn -> [Char] -> [Char]
$cshow :: NtfConn -> [Char]
show :: NtfConn -> [Char]
$cshowList :: [NtfConn] -> [Char] -> [Char]
showList :: [NtfConn] -> [Char] -> [Char]
Show)

-- msgTs is broker message timestamp, it is used in ConnMsgReq / APIGetConnNtfMessages
-- to set it as last connection message in case queue is empty
data NtfMsgInfo = NtfMsgInfo {NtfMsgInfo -> Text
msgId :: Text, NtfMsgInfo -> UTCTime
msgTs :: UTCTime}
  deriving (Int -> NtfMsgInfo -> [Char] -> [Char]
[NtfMsgInfo] -> [Char] -> [Char]
NtfMsgInfo -> [Char]
(Int -> NtfMsgInfo -> [Char] -> [Char])
-> (NtfMsgInfo -> [Char])
-> ([NtfMsgInfo] -> [Char] -> [Char])
-> Show NtfMsgInfo
forall a.
(Int -> a -> [Char] -> [Char])
-> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
$cshowsPrec :: Int -> NtfMsgInfo -> [Char] -> [Char]
showsPrec :: Int -> NtfMsgInfo -> [Char] -> [Char]
$cshow :: NtfMsgInfo -> [Char]
show :: NtfMsgInfo -> [Char]
$cshowList :: [NtfMsgInfo] -> [Char] -> [Char]
showList :: [NtfMsgInfo] -> [Char] -> [Char]
Show)

data RcvNtfMsgInfo
  = RNMInfo {RcvNtfMsgInfo -> Maybe NtfMsgInfo
ntfMsgInfo :: Maybe NtfMsgInfo}
  | RNMError {RcvNtfMsgInfo -> AgentErrorType
ntfMsgError :: AgentErrorType}
  deriving (Int -> RcvNtfMsgInfo -> [Char] -> [Char]
[RcvNtfMsgInfo] -> [Char] -> [Char]
RcvNtfMsgInfo -> [Char]
(Int -> RcvNtfMsgInfo -> [Char] -> [Char])
-> (RcvNtfMsgInfo -> [Char])
-> ([RcvNtfMsgInfo] -> [Char] -> [Char])
-> Show RcvNtfMsgInfo
forall a.
(Int -> a -> [Char] -> [Char])
-> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
$cshowsPrec :: Int -> RcvNtfMsgInfo -> [Char] -> [Char]
showsPrec :: Int -> RcvNtfMsgInfo -> [Char] -> [Char]
$cshow :: RcvNtfMsgInfo -> [Char]
show :: RcvNtfMsgInfo -> [Char]
$cshowList :: [RcvNtfMsgInfo] -> [Char] -> [Char]
showList :: [RcvNtfMsgInfo] -> [Char] -> [Char]
Show)

receivedMsgInfo :: Either AgentErrorType (Maybe SMPMsgMeta) -> RcvNtfMsgInfo
receivedMsgInfo :: Either AgentErrorType (Maybe SMPMsgMeta) -> RcvNtfMsgInfo
receivedMsgInfo = \case
  Right Maybe SMPMsgMeta
msgMeta_ -> Maybe NtfMsgInfo -> RcvNtfMsgInfo
RNMInfo (Maybe NtfMsgInfo -> RcvNtfMsgInfo)
-> Maybe NtfMsgInfo -> RcvNtfMsgInfo
forall a b. (a -> b) -> a -> b
$ (\SMPMsgMeta {MsgId
msgId :: MsgId
msgId :: SMPMsgMeta -> MsgId
msgId, SystemTime
msgTs :: SystemTime
msgTs :: SMPMsgMeta -> SystemTime
msgTs} -> MsgId -> SystemTime -> NtfMsgInfo
ntfMsgInfo_ MsgId
msgId SystemTime
msgTs) (SMPMsgMeta -> NtfMsgInfo) -> Maybe SMPMsgMeta -> Maybe NtfMsgInfo
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe SMPMsgMeta
msgMeta_
  Left AgentErrorType
e -> AgentErrorType -> RcvNtfMsgInfo
RNMError AgentErrorType
e

expectedMsgInfo :: NMsgMeta -> NtfMsgInfo
expectedMsgInfo :: NMsgMeta -> NtfMsgInfo
expectedMsgInfo NMsgMeta {MsgId
msgId :: MsgId
msgId :: NMsgMeta -> MsgId
msgId, SystemTime
msgTs :: SystemTime
msgTs :: NMsgMeta -> SystemTime
msgTs} = MsgId -> SystemTime -> NtfMsgInfo
ntfMsgInfo_ MsgId
msgId SystemTime
msgTs

ntfMsgInfo_ :: MsgId -> SystemTime -> NtfMsgInfo
ntfMsgInfo_ :: MsgId -> SystemTime -> NtfMsgInfo
ntfMsgInfo_ MsgId
msgId SystemTime
msgTs = NtfMsgInfo {msgId :: Text
msgId = MsgId -> Text
decodeLatin1 (MsgId -> Text) -> MsgId -> Text
forall a b. (a -> b) -> a -> b
$ MsgId -> MsgId
forall a. StrEncoding a => a -> MsgId
strEncode MsgId
msgId, msgTs :: UTCTime
msgTs = SystemTime -> UTCTime
systemToUTCTime SystemTime
msgTs}

-- Acknowledged message info - used to correlate with expected message
data NtfMsgAckInfo = NtfMsgAckInfo {NtfMsgAckInfo -> Text
msgId :: Text, NtfMsgAckInfo -> Maybe UTCTime
msgTs_ :: Maybe UTCTime}
  deriving (Int -> NtfMsgAckInfo -> [Char] -> [Char]
[NtfMsgAckInfo] -> [Char] -> [Char]
NtfMsgAckInfo -> [Char]
(Int -> NtfMsgAckInfo -> [Char] -> [Char])
-> (NtfMsgAckInfo -> [Char])
-> ([NtfMsgAckInfo] -> [Char] -> [Char])
-> Show NtfMsgAckInfo
forall a.
(Int -> a -> [Char] -> [Char])
-> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
$cshowsPrec :: Int -> NtfMsgAckInfo -> [Char] -> [Char]
showsPrec :: Int -> NtfMsgAckInfo -> [Char] -> [Char]
$cshow :: NtfMsgAckInfo -> [Char]
show :: NtfMsgAckInfo -> [Char]
$cshowList :: [NtfMsgAckInfo] -> [Char] -> [Char]
showList :: [NtfMsgAckInfo] -> [Char] -> [Char]
Show)

ntfMsgAckInfo :: MsgId -> Maybe UTCTime -> NtfMsgAckInfo
ntfMsgAckInfo :: MsgId -> Maybe UTCTime -> NtfMsgAckInfo
ntfMsgAckInfo MsgId
msgId Maybe UTCTime
msgTs_ = NtfMsgAckInfo {msgId :: Text
msgId = MsgId -> Text
decodeLatin1 (MsgId -> Text) -> MsgId -> Text
forall a b. (a -> b) -> a -> b
$ MsgId -> MsgId
forall a. StrEncoding a => a -> MsgId
strEncode MsgId
msgId, Maybe UTCTime
msgTs_ :: Maybe UTCTime
msgTs_ :: Maybe UTCTime
msgTs_}

crNtfToken :: (DeviceToken, NtfTknStatus, NotificationsMode, NtfServer) -> ChatResponse
crNtfToken :: (DeviceToken, NtfTknStatus, NotificationsMode, NtfServer)
-> ChatResponse
crNtfToken (DeviceToken
token, NtfTknStatus
status, NotificationsMode
ntfMode, NtfServer
ntfServer) = CRNtfToken {DeviceToken
token :: DeviceToken
token :: DeviceToken
token, NtfTknStatus
status :: NtfTknStatus
status :: NtfTknStatus
status, NotificationsMode
ntfMode :: NotificationsMode
ntfMode :: NotificationsMode
ntfMode, NtfServer
ntfServer :: NtfServer
ntfServer :: NtfServer
ntfServer}

data SwitchProgress = SwitchProgress
  { SwitchProgress -> QueueDirection
queueDirection :: QueueDirection,
    SwitchProgress -> SwitchPhase
switchPhase :: SwitchPhase,
    SwitchProgress -> ConnectionStats
connectionStats :: ConnectionStats
  }
  deriving (Int -> SwitchProgress -> [Char] -> [Char]
[SwitchProgress] -> [Char] -> [Char]
SwitchProgress -> [Char]
(Int -> SwitchProgress -> [Char] -> [Char])
-> (SwitchProgress -> [Char])
-> ([SwitchProgress] -> [Char] -> [Char])
-> Show SwitchProgress
forall a.
(Int -> a -> [Char] -> [Char])
-> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
$cshowsPrec :: Int -> SwitchProgress -> [Char] -> [Char]
showsPrec :: Int -> SwitchProgress -> [Char] -> [Char]
$cshow :: SwitchProgress -> [Char]
show :: SwitchProgress -> [Char]
$cshowList :: [SwitchProgress] -> [Char] -> [Char]
showList :: [SwitchProgress] -> [Char] -> [Char]
Show)

data RatchetSyncProgress = RatchetSyncProgress
  { RatchetSyncProgress -> RatchetSyncState
ratchetSyncStatus :: RatchetSyncState,
    RatchetSyncProgress -> ConnectionStats
connectionStats :: ConnectionStats
  }
  deriving (Int -> RatchetSyncProgress -> [Char] -> [Char]
[RatchetSyncProgress] -> [Char] -> [Char]
RatchetSyncProgress -> [Char]
(Int -> RatchetSyncProgress -> [Char] -> [Char])
-> (RatchetSyncProgress -> [Char])
-> ([RatchetSyncProgress] -> [Char] -> [Char])
-> Show RatchetSyncProgress
forall a.
(Int -> a -> [Char] -> [Char])
-> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
$cshowsPrec :: Int -> RatchetSyncProgress -> [Char] -> [Char]
showsPrec :: Int -> RatchetSyncProgress -> [Char] -> [Char]
$cshow :: RatchetSyncProgress -> [Char]
show :: RatchetSyncProgress -> [Char]
$cshowList :: [RatchetSyncProgress] -> [Char] -> [Char]
showList :: [RatchetSyncProgress] -> [Char] -> [Char]
Show)

data ParsedServerAddress = ParsedServerAddress
  { ParsedServerAddress -> Maybe ServerAddress
serverAddress :: Maybe ServerAddress,
    ParsedServerAddress -> [Char]
parseError :: String
  }
  deriving (Int -> ParsedServerAddress -> [Char] -> [Char]
[ParsedServerAddress] -> [Char] -> [Char]
ParsedServerAddress -> [Char]
(Int -> ParsedServerAddress -> [Char] -> [Char])
-> (ParsedServerAddress -> [Char])
-> ([ParsedServerAddress] -> [Char] -> [Char])
-> Show ParsedServerAddress
forall a.
(Int -> a -> [Char] -> [Char])
-> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
$cshowsPrec :: Int -> ParsedServerAddress -> [Char] -> [Char]
showsPrec :: Int -> ParsedServerAddress -> [Char] -> [Char]
$cshow :: ParsedServerAddress -> [Char]
show :: ParsedServerAddress -> [Char]
$cshowList :: [ParsedServerAddress] -> [Char] -> [Char]
showList :: [ParsedServerAddress] -> [Char] -> [Char]
Show)

data ServerAddress = ServerAddress
  { ServerAddress -> AProtocolType
serverProtocol :: AProtocolType,
    ServerAddress -> NonEmpty [Char]
hostnames :: NonEmpty String,
    ServerAddress -> [Char]
port :: String,
    ServerAddress -> [Char]
keyHash :: String,
    ServerAddress -> [Char]
basicAuth :: String
  }
  deriving (Int -> ServerAddress -> [Char] -> [Char]
[ServerAddress] -> [Char] -> [Char]
ServerAddress -> [Char]
(Int -> ServerAddress -> [Char] -> [Char])
-> (ServerAddress -> [Char])
-> ([ServerAddress] -> [Char] -> [Char])
-> Show ServerAddress
forall a.
(Int -> a -> [Char] -> [Char])
-> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
$cshowsPrec :: Int -> ServerAddress -> [Char] -> [Char]
showsPrec :: Int -> ServerAddress -> [Char] -> [Char]
$cshow :: ServerAddress -> [Char]
show :: ServerAddress -> [Char]
$cshowList :: [ServerAddress] -> [Char] -> [Char]
showList :: [ServerAddress] -> [Char] -> [Char]
Show)

data TimedMessagesEnabled
  = TMEEnableSetTTL Int
  | TMEEnableKeepTTL
  | TMEDisableKeepTTL
  deriving (Int -> TimedMessagesEnabled -> [Char] -> [Char]
[TimedMessagesEnabled] -> [Char] -> [Char]
TimedMessagesEnabled -> [Char]
(Int -> TimedMessagesEnabled -> [Char] -> [Char])
-> (TimedMessagesEnabled -> [Char])
-> ([TimedMessagesEnabled] -> [Char] -> [Char])
-> Show TimedMessagesEnabled
forall a.
(Int -> a -> [Char] -> [Char])
-> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
$cshowsPrec :: Int -> TimedMessagesEnabled -> [Char] -> [Char]
showsPrec :: Int -> TimedMessagesEnabled -> [Char] -> [Char]
$cshow :: TimedMessagesEnabled -> [Char]
show :: TimedMessagesEnabled -> [Char]
$cshowList :: [TimedMessagesEnabled] -> [Char] -> [Char]
showList :: [TimedMessagesEnabled] -> [Char] -> [Char]
Show)

tmeToPref :: Maybe Int -> TimedMessagesEnabled -> TimedMessagesPreference
tmeToPref :: Maybe Int -> TimedMessagesEnabled -> TimedMessagesPreference
tmeToPref Maybe Int
currentTTL TimedMessagesEnabled
tme = (FeatureAllowed -> Maybe Int -> TimedMessagesPreference)
-> (FeatureAllowed, Maybe Int) -> TimedMessagesPreference
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry FeatureAllowed -> Maybe Int -> TimedMessagesPreference
TimedMessagesPreference ((FeatureAllowed, Maybe Int) -> TimedMessagesPreference)
-> (FeatureAllowed, Maybe Int) -> TimedMessagesPreference
forall a b. (a -> b) -> a -> b
$ case TimedMessagesEnabled
tme of
  TMEEnableSetTTL Int
ttl -> (FeatureAllowed
FAYes, Int -> Maybe Int
forall a. a -> Maybe a
Just Int
ttl)
  TimedMessagesEnabled
TMEEnableKeepTTL -> (FeatureAllowed
FAYes, Maybe Int
currentTTL)
  TimedMessagesEnabled
TMEDisableKeepTTL -> (FeatureAllowed
FANo, Maybe Int
currentTTL)

data ChatItemDeletion = ChatItemDeletion
  { ChatItemDeletion -> AChatItem
deletedChatItem :: AChatItem,
    ChatItemDeletion -> Maybe AChatItem
toChatItem :: Maybe AChatItem
  }
  deriving (Int -> ChatItemDeletion -> [Char] -> [Char]
[ChatItemDeletion] -> [Char] -> [Char]
ChatItemDeletion -> [Char]
(Int -> ChatItemDeletion -> [Char] -> [Char])
-> (ChatItemDeletion -> [Char])
-> ([ChatItemDeletion] -> [Char] -> [Char])
-> Show ChatItemDeletion
forall a.
(Int -> a -> [Char] -> [Char])
-> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
$cshowsPrec :: Int -> ChatItemDeletion -> [Char] -> [Char]
showsPrec :: Int -> ChatItemDeletion -> [Char] -> [Char]
$cshow :: ChatItemDeletion -> [Char]
show :: ChatItemDeletion -> [Char]
$cshowList :: [ChatItemDeletion] -> [Char] -> [Char]
showList :: [ChatItemDeletion] -> [Char] -> [Char]
Show)

data ChatLogLevel = CLLDebug | CLLInfo | CLLWarning | CLLError | CLLImportant
  deriving (ChatLogLevel -> ChatLogLevel -> Bool
(ChatLogLevel -> ChatLogLevel -> Bool)
-> (ChatLogLevel -> ChatLogLevel -> Bool) -> Eq ChatLogLevel
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ChatLogLevel -> ChatLogLevel -> Bool
== :: ChatLogLevel -> ChatLogLevel -> Bool
$c/= :: ChatLogLevel -> ChatLogLevel -> Bool
/= :: ChatLogLevel -> ChatLogLevel -> Bool
Eq, Eq ChatLogLevel
Eq ChatLogLevel =>
(ChatLogLevel -> ChatLogLevel -> Ordering)
-> (ChatLogLevel -> ChatLogLevel -> Bool)
-> (ChatLogLevel -> ChatLogLevel -> Bool)
-> (ChatLogLevel -> ChatLogLevel -> Bool)
-> (ChatLogLevel -> ChatLogLevel -> Bool)
-> (ChatLogLevel -> ChatLogLevel -> ChatLogLevel)
-> (ChatLogLevel -> ChatLogLevel -> ChatLogLevel)
-> Ord ChatLogLevel
ChatLogLevel -> ChatLogLevel -> Bool
ChatLogLevel -> ChatLogLevel -> Ordering
ChatLogLevel -> ChatLogLevel -> ChatLogLevel
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: ChatLogLevel -> ChatLogLevel -> Ordering
compare :: ChatLogLevel -> ChatLogLevel -> Ordering
$c< :: ChatLogLevel -> ChatLogLevel -> Bool
< :: ChatLogLevel -> ChatLogLevel -> Bool
$c<= :: ChatLogLevel -> ChatLogLevel -> Bool
<= :: ChatLogLevel -> ChatLogLevel -> Bool
$c> :: ChatLogLevel -> ChatLogLevel -> Bool
> :: ChatLogLevel -> ChatLogLevel -> Bool
$c>= :: ChatLogLevel -> ChatLogLevel -> Bool
>= :: ChatLogLevel -> ChatLogLevel -> Bool
$cmax :: ChatLogLevel -> ChatLogLevel -> ChatLogLevel
max :: ChatLogLevel -> ChatLogLevel -> ChatLogLevel
$cmin :: ChatLogLevel -> ChatLogLevel -> ChatLogLevel
min :: ChatLogLevel -> ChatLogLevel -> ChatLogLevel
Ord, Int -> ChatLogLevel -> [Char] -> [Char]
[ChatLogLevel] -> [Char] -> [Char]
ChatLogLevel -> [Char]
(Int -> ChatLogLevel -> [Char] -> [Char])
-> (ChatLogLevel -> [Char])
-> ([ChatLogLevel] -> [Char] -> [Char])
-> Show ChatLogLevel
forall a.
(Int -> a -> [Char] -> [Char])
-> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
$cshowsPrec :: Int -> ChatLogLevel -> [Char] -> [Char]
showsPrec :: Int -> ChatLogLevel -> [Char] -> [Char]
$cshow :: ChatLogLevel -> [Char]
show :: ChatLogLevel -> [Char]
$cshowList :: [ChatLogLevel] -> [Char] -> [Char]
showList :: [ChatLogLevel] -> [Char] -> [Char]
Show)

data CoreVersionInfo = CoreVersionInfo
  { CoreVersionInfo -> [Char]
version :: String,
    CoreVersionInfo -> [Char]
simplexmqVersion :: String,
    CoreVersionInfo -> [Char]
simplexmqCommit :: String
  }
  deriving (Int -> CoreVersionInfo -> [Char] -> [Char]
[CoreVersionInfo] -> [Char] -> [Char]
CoreVersionInfo -> [Char]
(Int -> CoreVersionInfo -> [Char] -> [Char])
-> (CoreVersionInfo -> [Char])
-> ([CoreVersionInfo] -> [Char] -> [Char])
-> Show CoreVersionInfo
forall a.
(Int -> a -> [Char] -> [Char])
-> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
$cshowsPrec :: Int -> CoreVersionInfo -> [Char] -> [Char]
showsPrec :: Int -> CoreVersionInfo -> [Char] -> [Char]
$cshow :: CoreVersionInfo -> [Char]
show :: CoreVersionInfo -> [Char]
$cshowList :: [CoreVersionInfo] -> [Char] -> [Char]
showList :: [CoreVersionInfo] -> [Char] -> [Char]
Show)

#if !defined(dbPostgres)
data SlowSQLQuery = SlowSQLQuery
  { SlowSQLQuery -> Text
query :: Text,
    SlowSQLQuery -> SlowQueryStats
queryStats :: SlowQueryStats
  }
  deriving (Int -> SlowSQLQuery -> [Char] -> [Char]
[SlowSQLQuery] -> [Char] -> [Char]
SlowSQLQuery -> [Char]
(Int -> SlowSQLQuery -> [Char] -> [Char])
-> (SlowSQLQuery -> [Char])
-> ([SlowSQLQuery] -> [Char] -> [Char])
-> Show SlowSQLQuery
forall a.
(Int -> a -> [Char] -> [Char])
-> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
$cshowsPrec :: Int -> SlowSQLQuery -> [Char] -> [Char]
showsPrec :: Int -> SlowSQLQuery -> [Char] -> [Char]
$cshow :: SlowSQLQuery -> [Char]
show :: SlowSQLQuery -> [Char]
$cshowList :: [SlowSQLQuery] -> [Char] -> [Char]
showList :: [SlowSQLQuery] -> [Char] -> [Char]
Show)
#endif

data ChatError
  = ChatError {ChatError -> ChatErrorType
errorType :: ChatErrorType}
  | ChatErrorAgent {ChatError -> AgentErrorType
agentError :: AgentErrorType, ChatError -> AgentConnId
agentConnId :: AgentConnId, ChatError -> Maybe ConnectionEntity
connectionEntity_ :: Maybe ConnectionEntity}
  | ChatErrorStore {ChatError -> StoreError
storeError :: StoreError}
  | ChatErrorDatabase {ChatError -> DatabaseError
databaseError :: DatabaseError}
  | ChatErrorRemoteCtrl {ChatError -> RemoteCtrlError
remoteCtrlError :: RemoteCtrlError}
  | ChatErrorRemoteHost {ChatError -> RHKey
rhKey :: RHKey, ChatError -> RemoteHostError
remoteHostError :: RemoteHostError}
  deriving (Int -> ChatError -> [Char] -> [Char]
[ChatError] -> [Char] -> [Char]
ChatError -> [Char]
(Int -> ChatError -> [Char] -> [Char])
-> (ChatError -> [Char])
-> ([ChatError] -> [Char] -> [Char])
-> Show ChatError
forall a.
(Int -> a -> [Char] -> [Char])
-> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
$cshowsPrec :: Int -> ChatError -> [Char] -> [Char]
showsPrec :: Int -> ChatError -> [Char] -> [Char]
$cshow :: ChatError -> [Char]
show :: ChatError -> [Char]
$cshowList :: [ChatError] -> [Char] -> [Char]
showList :: [ChatError] -> [Char] -> [Char]
Show, Show ChatError
Typeable ChatError
(Typeable ChatError, Show ChatError) =>
(ChatError -> SomeException)
-> (SomeException -> Maybe ChatError)
-> (ChatError -> [Char])
-> Exception ChatError
SomeException -> Maybe ChatError
ChatError -> [Char]
ChatError -> SomeException
forall e.
(Typeable e, Show e) =>
(e -> SomeException)
-> (SomeException -> Maybe e) -> (e -> [Char]) -> Exception e
$ctoException :: ChatError -> SomeException
toException :: ChatError -> SomeException
$cfromException :: SomeException -> Maybe ChatError
fromException :: SomeException -> Maybe ChatError
$cdisplayException :: ChatError -> [Char]
displayException :: ChatError -> [Char]
Exception)

data ChatErrorType
  = CENoActiveUser
  | CENoConnectionUser {ChatErrorType -> AgentConnId
agentConnId :: AgentConnId}
  | CENoSndFileUser {ChatErrorType -> AgentSndFileId
agentSndFileId :: AgentSndFileId}
  | CENoRcvFileUser {ChatErrorType -> AgentRcvFileId
agentRcvFileId :: AgentRcvFileId}
  | CEUserUnknown
  | CEActiveUserExists -- TODO delete
  | CEUserExists {ChatErrorType -> Text
contactName :: ContactName}
  | CEDifferentActiveUser {ChatErrorType -> Int64
commandUserId :: UserId, ChatErrorType -> Int64
activeUserId :: UserId}
  | CECantDeleteActiveUser {ChatErrorType -> Int64
userId :: UserId}
  | CECantDeleteLastUser {userId :: UserId}
  | CECantHideLastUser {userId :: UserId}
  | CEHiddenUserAlwaysMuted {userId :: UserId}
  | CEEmptyUserPassword {userId :: UserId}
  | CEUserAlreadyHidden {userId :: UserId}
  | CEUserNotHidden {userId :: UserId}
  | CEInvalidDisplayName {ChatErrorType -> Text
displayName :: Text, ChatErrorType -> Text
validName :: Text}
  | CEChatNotStarted
  | CEChatNotStopped
  | CEChatStoreChanged
  | CEInvalidConnReq
  | CEUnsupportedConnReq
  | CEInvalidChatMessage {ChatErrorType -> Connection
connection :: Connection, ChatErrorType -> Maybe MsgMetaJSON
msgMeta :: Maybe MsgMetaJSON, ChatErrorType -> Text
messageData :: Text, ChatErrorType -> [Char]
message :: String}
  | CEConnReqMessageProhibited
  | CEContactNotFound {contactName :: ContactName, ChatErrorType -> Maybe (GroupInfo, GroupMember)
suspectedMember :: Maybe (GroupInfo, GroupMember)}
  | CEContactNotReady {ChatErrorType -> Contact
contact :: Contact}
  | CEContactNotActive {contact :: Contact}
  | CEContactDisabled {contact :: Contact}
  | CEConnectionDisabled {connection :: Connection}
  | CEGroupUserRole {ChatErrorType -> GroupInfo
groupInfo :: GroupInfo, ChatErrorType -> GroupMemberRole
requiredRole :: GroupMemberRole}
  | CEGroupMemberInitialRole {groupInfo :: GroupInfo, ChatErrorType -> GroupMemberRole
initialRole :: GroupMemberRole}
  | CEContactIncognitoCantInvite
  | CEGroupIncognitoCantInvite
  | CEGroupContactRole {contactName :: ContactName}
  | CEGroupDuplicateMember {contactName :: ContactName}
  | CEGroupDuplicateMemberId
  | CEGroupNotJoined {groupInfo :: GroupInfo}
  | CEGroupMemberNotActive
  | CECantBlockMemberForSelf {groupInfo :: GroupInfo, ChatErrorType -> GroupMember
member :: GroupMember, ChatErrorType -> Bool
setShowMessages :: Bool}
  | CEGroupMemberUserRemoved
  | CEGroupMemberNotFound
  | CEGroupCantResendInvitation {groupInfo :: GroupInfo, contactName :: ContactName}
  | CEGroupInternal {message :: String}
  | CEFileNotFound {message :: String}
  | CEFileSize {ChatErrorType -> [Char]
filePath :: FilePath}
  | CEFileAlreadyReceiving {message :: String}
  | CEFileCancelled {message :: String}
  | CEFileCancel {ChatErrorType -> Int64
fileId :: FileTransferId, message :: String}
  | CEFileAlreadyExists {filePath :: FilePath}
  | CEFileWrite {filePath :: FilePath, message :: String}
  | CEFileSend {fileId :: FileTransferId, ChatErrorType -> AgentErrorType
agentError :: AgentErrorType}
  | CEFileRcvChunk {message :: String}
  | CEFileInternal {message :: String}
  | CEFileImageType {filePath :: FilePath}
  | CEFileImageSize {filePath :: FilePath}
  | CEFileNotReceived {fileId :: FileTransferId}
  | CEFileNotApproved {fileId :: FileTransferId, ChatErrorType -> [XFTPServer]
unknownServers :: [XFTPServer]}
  | CEFallbackToSMPProhibited {fileId :: FileTransferId}
  | CEInlineFileProhibited {fileId :: FileTransferId}
  | CEInvalidForward
  | CEInvalidChatItemUpdate
  | CEInvalidChatItemDelete
  | CEHasCurrentCall
  | CENoCurrentCall
  | CECallContact {ChatErrorType -> Int64
contactId :: Int64}
  | CECallState {ChatErrorType -> CallStateTag
currentCallState :: CallStateTag}
  | CEDirectMessagesProhibited {ChatErrorType -> MsgDirection
direction :: MsgDirection, contact :: Contact}
  | CEAgentVersion
  | CEAgentNoSubResult {agentConnId :: AgentConnId}
  | CECommandError {message :: String}
  | CEServerProtocol {ChatErrorType -> AProtocolType
serverProtocol :: AProtocolType}
  | CEAgentCommandError {message :: String}
  | CEInvalidFileDescription {message :: String}
  | CEConnectionIncognitoChangeProhibited
  | CEConnectionUserChangeProhibited
  | CEPeerChatVRangeIncompatible
  | CEInternalError {message :: String}
  | CEException {message :: String}
  deriving (Int -> ChatErrorType -> [Char] -> [Char]
[ChatErrorType] -> [Char] -> [Char]
ChatErrorType -> [Char]
(Int -> ChatErrorType -> [Char] -> [Char])
-> (ChatErrorType -> [Char])
-> ([ChatErrorType] -> [Char] -> [Char])
-> Show ChatErrorType
forall a.
(Int -> a -> [Char] -> [Char])
-> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
$cshowsPrec :: Int -> ChatErrorType -> [Char] -> [Char]
showsPrec :: Int -> ChatErrorType -> [Char] -> [Char]
$cshow :: ChatErrorType -> [Char]
show :: ChatErrorType -> [Char]
$cshowList :: [ChatErrorType] -> [Char] -> [Char]
showList :: [ChatErrorType] -> [Char] -> [Char]
Show, Show ChatErrorType
Typeable ChatErrorType
(Typeable ChatErrorType, Show ChatErrorType) =>
(ChatErrorType -> SomeException)
-> (SomeException -> Maybe ChatErrorType)
-> (ChatErrorType -> [Char])
-> Exception ChatErrorType
SomeException -> Maybe ChatErrorType
ChatErrorType -> [Char]
ChatErrorType -> SomeException
forall e.
(Typeable e, Show e) =>
(e -> SomeException)
-> (SomeException -> Maybe e) -> (e -> [Char]) -> Exception e
$ctoException :: ChatErrorType -> SomeException
toException :: ChatErrorType -> SomeException
$cfromException :: SomeException -> Maybe ChatErrorType
fromException :: SomeException -> Maybe ChatErrorType
$cdisplayException :: ChatErrorType -> [Char]
displayException :: ChatErrorType -> [Char]
Exception)

data DatabaseError
  = DBErrorEncrypted
  | DBErrorPlaintext
  | DBErrorNoFile {DatabaseError -> [Char]
dbFile :: String}
  | DBErrorExport {DatabaseError -> SQLiteError
sqliteError :: SQLiteError}
  | DBErrorOpen {sqliteError :: SQLiteError}
  deriving (Int -> DatabaseError -> [Char] -> [Char]
[DatabaseError] -> [Char] -> [Char]
DatabaseError -> [Char]
(Int -> DatabaseError -> [Char] -> [Char])
-> (DatabaseError -> [Char])
-> ([DatabaseError] -> [Char] -> [Char])
-> Show DatabaseError
forall a.
(Int -> a -> [Char] -> [Char])
-> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
$cshowsPrec :: Int -> DatabaseError -> [Char] -> [Char]
showsPrec :: Int -> DatabaseError -> [Char] -> [Char]
$cshow :: DatabaseError -> [Char]
show :: DatabaseError -> [Char]
$cshowList :: [DatabaseError] -> [Char] -> [Char]
showList :: [DatabaseError] -> [Char] -> [Char]
Show, Show DatabaseError
Typeable DatabaseError
(Typeable DatabaseError, Show DatabaseError) =>
(DatabaseError -> SomeException)
-> (SomeException -> Maybe DatabaseError)
-> (DatabaseError -> [Char])
-> Exception DatabaseError
SomeException -> Maybe DatabaseError
DatabaseError -> [Char]
DatabaseError -> SomeException
forall e.
(Typeable e, Show e) =>
(e -> SomeException)
-> (SomeException -> Maybe e) -> (e -> [Char]) -> Exception e
$ctoException :: DatabaseError -> SomeException
toException :: DatabaseError -> SomeException
$cfromException :: SomeException -> Maybe DatabaseError
fromException :: SomeException -> Maybe DatabaseError
$cdisplayException :: DatabaseError -> [Char]
displayException :: DatabaseError -> [Char]
Exception)

data SQLiteError = SQLiteErrorNotADatabase | SQLiteError {SQLiteError -> [Char]
dbError :: String}
  deriving (Int -> SQLiteError -> [Char] -> [Char]
[SQLiteError] -> [Char] -> [Char]
SQLiteError -> [Char]
(Int -> SQLiteError -> [Char] -> [Char])
-> (SQLiteError -> [Char])
-> ([SQLiteError] -> [Char] -> [Char])
-> Show SQLiteError
forall a.
(Int -> a -> [Char] -> [Char])
-> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
$cshowsPrec :: Int -> SQLiteError -> [Char] -> [Char]
showsPrec :: Int -> SQLiteError -> [Char] -> [Char]
$cshow :: SQLiteError -> [Char]
show :: SQLiteError -> [Char]
$cshowList :: [SQLiteError] -> [Char] -> [Char]
showList :: [SQLiteError] -> [Char] -> [Char]
Show, Show SQLiteError
Typeable SQLiteError
(Typeable SQLiteError, Show SQLiteError) =>
(SQLiteError -> SomeException)
-> (SomeException -> Maybe SQLiteError)
-> (SQLiteError -> [Char])
-> Exception SQLiteError
SomeException -> Maybe SQLiteError
SQLiteError -> [Char]
SQLiteError -> SomeException
forall e.
(Typeable e, Show e) =>
(e -> SomeException)
-> (SomeException -> Maybe e) -> (e -> [Char]) -> Exception e
$ctoException :: SQLiteError -> SomeException
toException :: SQLiteError -> SomeException
$cfromException :: SomeException -> Maybe SQLiteError
fromException :: SomeException -> Maybe SQLiteError
$cdisplayException :: SQLiteError -> [Char]
displayException :: SQLiteError -> [Char]
Exception)

throwDBError :: DatabaseError -> CM ()
throwDBError :: DatabaseError -> CM ()
throwDBError = ChatError -> CM ()
forall a.
ChatError -> ExceptT ChatError (ReaderT ChatController IO) a
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (ChatError -> CM ())
-> (DatabaseError -> ChatError) -> DatabaseError -> CM ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DatabaseError -> ChatError
ChatErrorDatabase

-- TODO review errors, some of it can be covered by HTTP2 errors
data RemoteHostError
  = RHEMissing -- No remote session matches this identifier
  | RHEInactive -- A session exists, but not active
  | RHEBusy -- A session is already running
  | RHETimeout
  | RHEBadState -- Illegal state transition
  | RHEBadVersion {RemoteHostError -> AppVersion
appVersion :: AppVersion}
  | RHELocalCommand -- Command not allowed for remote execution
  | RHEDisconnected {RemoteHostError -> Text
reason :: Text} -- TODO should be sent when disconnected?
  | RHEProtocolError RemoteProtocolError
  deriving (Int -> RemoteHostError -> [Char] -> [Char]
[RemoteHostError] -> [Char] -> [Char]
RemoteHostError -> [Char]
(Int -> RemoteHostError -> [Char] -> [Char])
-> (RemoteHostError -> [Char])
-> ([RemoteHostError] -> [Char] -> [Char])
-> Show RemoteHostError
forall a.
(Int -> a -> [Char] -> [Char])
-> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
$cshowsPrec :: Int -> RemoteHostError -> [Char] -> [Char]
showsPrec :: Int -> RemoteHostError -> [Char] -> [Char]
$cshow :: RemoteHostError -> [Char]
show :: RemoteHostError -> [Char]
$cshowList :: [RemoteHostError] -> [Char] -> [Char]
showList :: [RemoteHostError] -> [Char] -> [Char]
Show, Show RemoteHostError
Typeable RemoteHostError
(Typeable RemoteHostError, Show RemoteHostError) =>
(RemoteHostError -> SomeException)
-> (SomeException -> Maybe RemoteHostError)
-> (RemoteHostError -> [Char])
-> Exception RemoteHostError
SomeException -> Maybe RemoteHostError
RemoteHostError -> [Char]
RemoteHostError -> SomeException
forall e.
(Typeable e, Show e) =>
(e -> SomeException)
-> (SomeException -> Maybe e) -> (e -> [Char]) -> Exception e
$ctoException :: RemoteHostError -> SomeException
toException :: RemoteHostError -> SomeException
$cfromException :: SomeException -> Maybe RemoteHostError
fromException :: SomeException -> Maybe RemoteHostError
$cdisplayException :: RemoteHostError -> [Char]
displayException :: RemoteHostError -> [Char]
Exception)

data RemoteHostStopReason
  = RHSRConnectionFailed {RemoteHostStopReason -> ChatError
chatError :: ChatError}
  | RHSRCrashed {chatError :: ChatError}
  | RHSRDisconnected
  deriving (Int -> RemoteHostStopReason -> [Char] -> [Char]
[RemoteHostStopReason] -> [Char] -> [Char]
RemoteHostStopReason -> [Char]
(Int -> RemoteHostStopReason -> [Char] -> [Char])
-> (RemoteHostStopReason -> [Char])
-> ([RemoteHostStopReason] -> [Char] -> [Char])
-> Show RemoteHostStopReason
forall a.
(Int -> a -> [Char] -> [Char])
-> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
$cshowsPrec :: Int -> RemoteHostStopReason -> [Char] -> [Char]
showsPrec :: Int -> RemoteHostStopReason -> [Char] -> [Char]
$cshow :: RemoteHostStopReason -> [Char]
show :: RemoteHostStopReason -> [Char]
$cshowList :: [RemoteHostStopReason] -> [Char] -> [Char]
showList :: [RemoteHostStopReason] -> [Char] -> [Char]
Show, Show RemoteHostStopReason
Typeable RemoteHostStopReason
(Typeable RemoteHostStopReason, Show RemoteHostStopReason) =>
(RemoteHostStopReason -> SomeException)
-> (SomeException -> Maybe RemoteHostStopReason)
-> (RemoteHostStopReason -> [Char])
-> Exception RemoteHostStopReason
SomeException -> Maybe RemoteHostStopReason
RemoteHostStopReason -> [Char]
RemoteHostStopReason -> SomeException
forall e.
(Typeable e, Show e) =>
(e -> SomeException)
-> (SomeException -> Maybe e) -> (e -> [Char]) -> Exception e
$ctoException :: RemoteHostStopReason -> SomeException
toException :: RemoteHostStopReason -> SomeException
$cfromException :: SomeException -> Maybe RemoteHostStopReason
fromException :: SomeException -> Maybe RemoteHostStopReason
$cdisplayException :: RemoteHostStopReason -> [Char]
displayException :: RemoteHostStopReason -> [Char]
Exception)

-- TODO review errors, some of it can be covered by HTTP2 errors
data RemoteCtrlError
  = RCEInactive -- No session is running
  | RCEBadState -- A session is in a wrong state for the current operation
  | RCEBusy -- A session is already running
  | RCETimeout
  | RCENoKnownControllers -- No previously-contacted controllers to discover
  | RCEBadController -- Attempting to confirm a found controller with another ID
  | -- | A session disconnected by a controller
    RCEDisconnected {RemoteCtrlError -> Int64
remoteCtrlId :: RemoteCtrlId, RemoteCtrlError -> Text
reason :: Text}
  | RCEBadInvitation
  | RCEBadVersion {RemoteCtrlError -> AppVersion
appVersion :: AppVersion}
  | RCEHTTP2Error {RemoteCtrlError -> Text
http2Error :: Text} -- TODO currently not used
  | RCEProtocolError {RemoteCtrlError -> RemoteProtocolError
protocolError :: RemoteProtocolError}
  deriving (Int -> RemoteCtrlError -> [Char] -> [Char]
[RemoteCtrlError] -> [Char] -> [Char]
RemoteCtrlError -> [Char]
(Int -> RemoteCtrlError -> [Char] -> [Char])
-> (RemoteCtrlError -> [Char])
-> ([RemoteCtrlError] -> [Char] -> [Char])
-> Show RemoteCtrlError
forall a.
(Int -> a -> [Char] -> [Char])
-> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
$cshowsPrec :: Int -> RemoteCtrlError -> [Char] -> [Char]
showsPrec :: Int -> RemoteCtrlError -> [Char] -> [Char]
$cshow :: RemoteCtrlError -> [Char]
show :: RemoteCtrlError -> [Char]
$cshowList :: [RemoteCtrlError] -> [Char] -> [Char]
showList :: [RemoteCtrlError] -> [Char] -> [Char]
Show, Show RemoteCtrlError
Typeable RemoteCtrlError
(Typeable RemoteCtrlError, Show RemoteCtrlError) =>
(RemoteCtrlError -> SomeException)
-> (SomeException -> Maybe RemoteCtrlError)
-> (RemoteCtrlError -> [Char])
-> Exception RemoteCtrlError
SomeException -> Maybe RemoteCtrlError
RemoteCtrlError -> [Char]
RemoteCtrlError -> SomeException
forall e.
(Typeable e, Show e) =>
(e -> SomeException)
-> (SomeException -> Maybe e) -> (e -> [Char]) -> Exception e
$ctoException :: RemoteCtrlError -> SomeException
toException :: RemoteCtrlError -> SomeException
$cfromException :: SomeException -> Maybe RemoteCtrlError
fromException :: SomeException -> Maybe RemoteCtrlError
$cdisplayException :: RemoteCtrlError -> [Char]
displayException :: RemoteCtrlError -> [Char]
Exception)

data RemoteCtrlStopReason
  = RCSRDiscoveryFailed {RemoteCtrlStopReason -> ChatError
chatError :: ChatError}
  | RCSRConnectionFailed {chatError :: ChatError}
  | RCSRSetupFailed {chatError :: ChatError}
  | RCSRDisconnected
  deriving (Int -> RemoteCtrlStopReason -> [Char] -> [Char]
[RemoteCtrlStopReason] -> [Char] -> [Char]
RemoteCtrlStopReason -> [Char]
(Int -> RemoteCtrlStopReason -> [Char] -> [Char])
-> (RemoteCtrlStopReason -> [Char])
-> ([RemoteCtrlStopReason] -> [Char] -> [Char])
-> Show RemoteCtrlStopReason
forall a.
(Int -> a -> [Char] -> [Char])
-> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
$cshowsPrec :: Int -> RemoteCtrlStopReason -> [Char] -> [Char]
showsPrec :: Int -> RemoteCtrlStopReason -> [Char] -> [Char]
$cshow :: RemoteCtrlStopReason -> [Char]
show :: RemoteCtrlStopReason -> [Char]
$cshowList :: [RemoteCtrlStopReason] -> [Char] -> [Char]
showList :: [RemoteCtrlStopReason] -> [Char] -> [Char]
Show, Show RemoteCtrlStopReason
Typeable RemoteCtrlStopReason
(Typeable RemoteCtrlStopReason, Show RemoteCtrlStopReason) =>
(RemoteCtrlStopReason -> SomeException)
-> (SomeException -> Maybe RemoteCtrlStopReason)
-> (RemoteCtrlStopReason -> [Char])
-> Exception RemoteCtrlStopReason
SomeException -> Maybe RemoteCtrlStopReason
RemoteCtrlStopReason -> [Char]
RemoteCtrlStopReason -> SomeException
forall e.
(Typeable e, Show e) =>
(e -> SomeException)
-> (SomeException -> Maybe e) -> (e -> [Char]) -> Exception e
$ctoException :: RemoteCtrlStopReason -> SomeException
toException :: RemoteCtrlStopReason -> SomeException
$cfromException :: SomeException -> Maybe RemoteCtrlStopReason
fromException :: SomeException -> Maybe RemoteCtrlStopReason
$cdisplayException :: RemoteCtrlStopReason -> [Char]
displayException :: RemoteCtrlStopReason -> [Char]
Exception)

data ArchiveError
  = AEImport {ArchiveError -> [Char]
importError :: String}
  | AEFileError {ArchiveError -> [Char]
file :: String, ArchiveError -> [Char]
fileError :: String}
  deriving (Int -> ArchiveError -> [Char] -> [Char]
[ArchiveError] -> [Char] -> [Char]
ArchiveError -> [Char]
(Int -> ArchiveError -> [Char] -> [Char])
-> (ArchiveError -> [Char])
-> ([ArchiveError] -> [Char] -> [Char])
-> Show ArchiveError
forall a.
(Int -> a -> [Char] -> [Char])
-> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
$cshowsPrec :: Int -> ArchiveError -> [Char] -> [Char]
showsPrec :: Int -> ArchiveError -> [Char] -> [Char]
$cshow :: ArchiveError -> [Char]
show :: ArchiveError -> [Char]
$cshowList :: [ArchiveError] -> [Char] -> [Char]
showList :: [ArchiveError] -> [Char] -> [Char]
Show, Show ArchiveError
Typeable ArchiveError
(Typeable ArchiveError, Show ArchiveError) =>
(ArchiveError -> SomeException)
-> (SomeException -> Maybe ArchiveError)
-> (ArchiveError -> [Char])
-> Exception ArchiveError
SomeException -> Maybe ArchiveError
ArchiveError -> [Char]
ArchiveError -> SomeException
forall e.
(Typeable e, Show e) =>
(e -> SomeException)
-> (SomeException -> Maybe e) -> (e -> [Char]) -> Exception e
$ctoException :: ArchiveError -> SomeException
toException :: ArchiveError -> SomeException
$cfromException :: SomeException -> Maybe ArchiveError
fromException :: SomeException -> Maybe ArchiveError
$cdisplayException :: ArchiveError -> [Char]
displayException :: ArchiveError -> [Char]
Exception)

instance AnyError ChatError where
  fromSomeException :: SomeException -> ChatError
fromSomeException = ChatErrorType -> ChatError
ChatError (ChatErrorType -> ChatError)
-> (SomeException -> ChatErrorType) -> SomeException -> ChatError
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> ChatErrorType
CEException ([Char] -> ChatErrorType)
-> (SomeException -> [Char]) -> SomeException -> ChatErrorType
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SomeException -> [Char]
forall a. Show a => a -> [Char]
show
  {-# INLINE fromSomeException #-}

-- | Host (mobile) side of transport to process remote commands and forward notifications
data RemoteCtrlSession
  = RCSessionStarting
  | RCSessionSearching
      { RemoteCtrlSession -> Async ()
action :: Async (),
        RemoteCtrlSession -> TMVar (RemoteCtrl, RCVerifiedInvitation)
foundCtrl :: TMVar (RemoteCtrl, RCVerifiedInvitation)
      }
  | RCSessionConnecting
      { RemoteCtrlSession -> Maybe Int64
remoteCtrlId_ :: Maybe RemoteCtrlId,
        RemoteCtrlSession -> RCCtrlClient
rcsClient :: RCCtrlClient,
        RemoteCtrlSession -> Async ()
rcsWaitSession :: Async ()
      }
  | RCSessionPendingConfirmation
      { remoteCtrlId_ :: Maybe RemoteCtrlId,
        RemoteCtrlSession -> Text
ctrlDeviceName :: Text,
        rcsClient :: RCCtrlClient,
        RemoteCtrlSession -> TLS 'TClient
tls :: TLS 'TClient,
        RemoteCtrlSession -> Text
sessionCode :: Text,
        rcsWaitSession :: Async (),
        RemoteCtrlSession
-> TMVar (Either RCErrorType (RCCtrlSession, RCCtrlPairing))
rcsWaitConfirmation :: TMVar (Either RCErrorType (RCCtrlSession, RCCtrlPairing))
      }
  | RCSessionConnected
      { RemoteCtrlSession -> Int64
remoteCtrlId :: RemoteCtrlId,
        rcsClient :: RCCtrlClient,
        tls :: TLS 'TClient,
        RemoteCtrlSession -> RCCtrlSession
rcsSession :: RCCtrlSession,
        RemoteCtrlSession -> Async ()
http2Server :: Async (),
        RemoteCtrlSession -> TBQueue (Either ChatError ChatEvent)
remoteOutputQ :: TBQueue (Either ChatError ChatEvent)
      }

data RemoteCtrlSessionState
  = RCSStarting
  | RCSSearching
  | RCSConnecting
  | RCSPendingConfirmation {RemoteCtrlSessionState -> Text
sessionCode :: Text}
  | RCSConnected {sessionCode :: Text}
  deriving (Int -> RemoteCtrlSessionState -> [Char] -> [Char]
[RemoteCtrlSessionState] -> [Char] -> [Char]
RemoteCtrlSessionState -> [Char]
(Int -> RemoteCtrlSessionState -> [Char] -> [Char])
-> (RemoteCtrlSessionState -> [Char])
-> ([RemoteCtrlSessionState] -> [Char] -> [Char])
-> Show RemoteCtrlSessionState
forall a.
(Int -> a -> [Char] -> [Char])
-> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
$cshowsPrec :: Int -> RemoteCtrlSessionState -> [Char] -> [Char]
showsPrec :: Int -> RemoteCtrlSessionState -> [Char] -> [Char]
$cshow :: RemoteCtrlSessionState -> [Char]
show :: RemoteCtrlSessionState -> [Char]
$cshowList :: [RemoteCtrlSessionState] -> [Char] -> [Char]
showList :: [RemoteCtrlSessionState] -> [Char] -> [Char]
Show)

rcsSessionState :: RemoteCtrlSession -> RemoteCtrlSessionState
rcsSessionState :: RemoteCtrlSession -> RemoteCtrlSessionState
rcsSessionState = \case
  RemoteCtrlSession
RCSessionStarting -> RemoteCtrlSessionState
RCSStarting
  RCSessionSearching {} -> RemoteCtrlSessionState
RCSSearching
  RCSessionConnecting {} -> RemoteCtrlSessionState
RCSConnecting
  RCSessionPendingConfirmation {TLS 'TClient
tls :: RemoteCtrlSession -> TLS 'TClient
tls :: TLS 'TClient
tls} -> RCSPendingConfirmation {sessionCode :: Text
sessionCode = TLS 'TClient -> Text
forall (p :: TransportPeer). TLS p -> Text
tlsSessionCode TLS 'TClient
tls}
  RCSessionConnected {TLS 'TClient
tls :: RemoteCtrlSession -> TLS 'TClient
tls :: TLS 'TClient
tls} -> RCSConnected {sessionCode :: Text
sessionCode = TLS 'TClient -> Text
forall (p :: TransportPeer). TLS p -> Text
tlsSessionCode TLS 'TClient
tls}

-- | UI-accessible remote controller information
data RemoteCtrlInfo = RemoteCtrlInfo
  { RemoteCtrlInfo -> Int64
remoteCtrlId :: RemoteCtrlId,
    RemoteCtrlInfo -> Text
ctrlDeviceName :: Text,
    RemoteCtrlInfo -> Maybe RemoteCtrlSessionState
sessionState :: Maybe RemoteCtrlSessionState
  }
  deriving (Int -> RemoteCtrlInfo -> [Char] -> [Char]
[RemoteCtrlInfo] -> [Char] -> [Char]
RemoteCtrlInfo -> [Char]
(Int -> RemoteCtrlInfo -> [Char] -> [Char])
-> (RemoteCtrlInfo -> [Char])
-> ([RemoteCtrlInfo] -> [Char] -> [Char])
-> Show RemoteCtrlInfo
forall a.
(Int -> a -> [Char] -> [Char])
-> (a -> [Char]) -> ([a] -> [Char] -> [Char]) -> Show a
$cshowsPrec :: Int -> RemoteCtrlInfo -> [Char] -> [Char]
showsPrec :: Int -> RemoteCtrlInfo -> [Char] -> [Char]
$cshow :: RemoteCtrlInfo -> [Char]
show :: RemoteCtrlInfo -> [Char]
$cshowList :: [RemoteCtrlInfo] -> [Char] -> [Char]
showList :: [RemoteCtrlInfo] -> [Char] -> [Char]
Show)

type CM' a = ReaderT ChatController IO a

type CM a = ExceptT ChatError (ReaderT ChatController IO) a

chatReadVar :: (ChatController -> TVar a) -> CM a
chatReadVar :: forall a. (ChatController -> TVar a) -> CM a
chatReadVar = ReaderT ChatController IO a
-> ExceptT ChatError (ReaderT ChatController IO) a
forall (m :: * -> *) a. Monad m => m a -> ExceptT ChatError m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (ReaderT ChatController IO a
 -> ExceptT ChatError (ReaderT ChatController IO) a)
-> ((ChatController -> TVar a) -> ReaderT ChatController IO a)
-> (ChatController -> TVar a)
-> ExceptT ChatError (ReaderT ChatController IO) a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ChatController -> TVar a) -> ReaderT ChatController IO a
forall a. (ChatController -> TVar a) -> CM' a
chatReadVar'
{-# INLINE chatReadVar #-}

chatReadVar' :: (ChatController -> TVar a) -> CM' a
chatReadVar' :: forall a. (ChatController -> TVar a) -> CM' a
chatReadVar' ChatController -> TVar a
f = (ChatController -> TVar a) -> ReaderT ChatController IO (TVar a)
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks ChatController -> TVar a
f ReaderT ChatController IO (TVar a)
-> (TVar a -> ReaderT ChatController IO a)
-> ReaderT ChatController IO a
forall a b.
ReaderT ChatController IO a
-> (a -> ReaderT ChatController IO b)
-> ReaderT ChatController IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= TVar a -> ReaderT ChatController IO a
forall (m :: * -> *) a. MonadIO m => TVar a -> m a
readTVarIO
{-# INLINE chatReadVar' #-}

chatWriteVar :: (ChatController -> TVar a) -> a -> CM ()
chatWriteVar :: forall a. (ChatController -> TVar a) -> a -> CM ()
chatWriteVar ChatController -> TVar a
f = ReaderT ChatController IO () -> CM ()
forall (m :: * -> *) a. Monad m => m a -> ExceptT ChatError m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (ReaderT ChatController IO () -> CM ())
-> (a -> ReaderT ChatController IO ()) -> a -> CM ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ChatController -> TVar a) -> a -> ReaderT ChatController IO ()
forall a.
(ChatController -> TVar a) -> a -> ReaderT ChatController IO ()
chatWriteVar' ChatController -> TVar a
f
{-# INLINE chatWriteVar #-}

chatWriteVar' :: (ChatController -> TVar a) -> a -> CM' ()
chatWriteVar' :: forall a.
(ChatController -> TVar a) -> a -> ReaderT ChatController IO ()
chatWriteVar' ChatController -> TVar a
f a
value = (ChatController -> TVar a) -> ReaderT ChatController IO (TVar a)
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks ChatController -> TVar a
f ReaderT ChatController IO (TVar a)
-> (TVar a -> ReaderT ChatController IO ())
-> ReaderT ChatController IO ()
forall a b.
ReaderT ChatController IO a
-> (a -> ReaderT ChatController IO b)
-> ReaderT ChatController IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= STM () -> ReaderT ChatController IO ()
forall (m :: * -> *) a. MonadIO m => STM a -> m a
atomically (STM () -> ReaderT ChatController IO ())
-> (TVar a -> STM ()) -> TVar a -> ReaderT ChatController IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (TVar a -> a -> STM ()
forall a. TVar a -> a -> STM ()
`writeTVar` a
value)
{-# INLINE chatWriteVar' #-}

chatModifyVar :: (ChatController -> TVar a) -> (a -> a) -> CM ()
chatModifyVar :: forall a. (ChatController -> TVar a) -> (a -> a) -> CM ()
chatModifyVar ChatController -> TVar a
f = ReaderT ChatController IO () -> CM ()
forall (m :: * -> *) a. Monad m => m a -> ExceptT ChatError m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (ReaderT ChatController IO () -> CM ())
-> ((a -> a) -> ReaderT ChatController IO ()) -> (a -> a) -> CM ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ChatController -> TVar a)
-> (a -> a) -> ReaderT ChatController IO ()
forall a.
(ChatController -> TVar a)
-> (a -> a) -> ReaderT ChatController IO ()
chatModifyVar' ChatController -> TVar a
f
{-# INLINE chatModifyVar #-}

chatModifyVar' :: (ChatController -> TVar a) -> (a -> a) -> CM' ()
chatModifyVar' :: forall a.
(ChatController -> TVar a)
-> (a -> a) -> ReaderT ChatController IO ()
chatModifyVar' ChatController -> TVar a
f a -> a
newValue = (ChatController -> TVar a) -> ReaderT ChatController IO (TVar a)
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks ChatController -> TVar a
f ReaderT ChatController IO (TVar a)
-> (TVar a -> ReaderT ChatController IO ())
-> ReaderT ChatController IO ()
forall a b.
ReaderT ChatController IO a
-> (a -> ReaderT ChatController IO b)
-> ReaderT ChatController IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= STM () -> ReaderT ChatController IO ()
forall (m :: * -> *) a. MonadIO m => STM a -> m a
atomically (STM () -> ReaderT ChatController IO ())
-> (TVar a -> STM ()) -> TVar a -> ReaderT ChatController IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (TVar a -> (a -> a) -> STM ()
forall a. TVar a -> (a -> a) -> STM ()
`modifyTVar'` a -> a
newValue)
{-# INLINE chatModifyVar' #-}

onChatError :: CM a -> CM b -> CM a
CM a
a onChatError :: forall a b. CM a -> CM b -> CM a
`onChatError` CM b
onErr = CM a
a CM a -> (ChatError -> CM a) -> CM a
forall e (m :: * -> *) a.
(AnyError e, MonadUnliftIO m) =>
ExceptT e m a -> (e -> ExceptT e m a) -> ExceptT e m a
`catchAllErrors` \ChatError
e -> CM b
onErr CM b -> CM a -> CM a
forall a b.
ExceptT ChatError (ReaderT ChatController IO) a
-> ExceptT ChatError (ReaderT ChatController IO) b
-> ExceptT ChatError (ReaderT ChatController IO) b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ChatError -> CM a
forall a.
ChatError -> ExceptT ChatError (ReaderT ChatController IO) a
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError ChatError
e
{-# INLINE onChatError #-}

throwCmdError :: String -> CM a
throwCmdError :: forall a. [Char] -> CM a
throwCmdError = ChatError -> ExceptT ChatError (ReaderT ChatController IO) a
forall a.
ChatError -> ExceptT ChatError (ReaderT ChatController IO) a
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (ChatError -> ExceptT ChatError (ReaderT ChatController IO) a)
-> ([Char] -> ChatError)
-> [Char]
-> ExceptT ChatError (ReaderT ChatController IO) a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ChatErrorType -> ChatError
ChatError (ChatErrorType -> ChatError)
-> ([Char] -> ChatErrorType) -> [Char] -> ChatError
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> ChatErrorType
CECommandError
{-# INLINE throwCmdError #-}

chatCmdError :: String -> Either ChatError ChatResponse
chatCmdError :: [Char] -> Either ChatError ChatResponse
chatCmdError = ChatError -> Either ChatError ChatResponse
forall a b. a -> Either a b
Left (ChatError -> Either ChatError ChatResponse)
-> ([Char] -> ChatError) -> [Char] -> Either ChatError ChatResponse
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ChatErrorType -> ChatError
ChatError (ChatErrorType -> ChatError)
-> ([Char] -> ChatErrorType) -> [Char] -> ChatError
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> ChatErrorType
CECommandError
{-# INLINE chatCmdError #-}

throwChatError :: ChatErrorType -> CM a
throwChatError :: forall a. ChatErrorType -> CM a
throwChatError = ChatError -> ExceptT ChatError (ReaderT ChatController IO) a
forall a.
ChatError -> ExceptT ChatError (ReaderT ChatController IO) a
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (ChatError -> ExceptT ChatError (ReaderT ChatController IO) a)
-> (ChatErrorType -> ChatError)
-> ChatErrorType
-> ExceptT ChatError (ReaderT ChatController IO) a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ChatErrorType -> ChatError
ChatError
{-# INLINE throwChatError #-}

toViewTE :: TerminalEvent -> CM ()
toViewTE :: TerminalEvent -> CM ()
toViewTE = ChatEvent -> CM ()
toView (ChatEvent -> CM ())
-> (TerminalEvent -> ChatEvent) -> TerminalEvent -> CM ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TerminalEvent -> ChatEvent
CEvtTerminalEvent
{-# INLINE toViewTE #-}

-- | Emit local events.
toView :: ChatEvent -> CM ()
toView :: ChatEvent -> CM ()
toView = ReaderT ChatController IO () -> CM ()
forall (m :: * -> *) a. Monad m => m a -> ExceptT ChatError m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (ReaderT ChatController IO () -> CM ())
-> (ChatEvent -> ReaderT ChatController IO ())
-> ChatEvent
-> CM ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ChatEvent -> ReaderT ChatController IO ()
toView'
{-# INLINE toView #-}

toView' :: ChatEvent -> CM' ()
toView' :: ChatEvent -> ReaderT ChatController IO ()
toView' = Either ChatError ChatEvent -> ReaderT ChatController IO ()
toView_ (Either ChatError ChatEvent -> ReaderT ChatController IO ())
-> (ChatEvent -> Either ChatError ChatEvent)
-> ChatEvent
-> ReaderT ChatController IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ChatEvent -> Either ChatError ChatEvent
forall a b. b -> Either a b
Right
{-# INLINE toView' #-}

eToView :: ChatError -> CM ()
eToView :: ChatError -> CM ()
eToView = ReaderT ChatController IO () -> CM ()
forall (m :: * -> *) a. Monad m => m a -> ExceptT ChatError m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (ReaderT ChatController IO () -> CM ())
-> (ChatError -> ReaderT ChatController IO ())
-> ChatError
-> CM ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ChatError -> ReaderT ChatController IO ()
eToView'
{-# INLINE eToView #-}

eToView' :: ChatError -> CM' ()
eToView' :: ChatError -> ReaderT ChatController IO ()
eToView' = Either ChatError ChatEvent -> ReaderT ChatController IO ()
toView_ (Either ChatError ChatEvent -> ReaderT ChatController IO ())
-> (ChatError -> Either ChatError ChatEvent)
-> ChatError
-> ReaderT ChatController IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ChatError -> Either ChatError ChatEvent
forall a b. a -> Either a b
Left
{-# INLINE eToView' #-}

toView_ :: Either ChatError ChatEvent -> CM' ()
toView_ :: Either ChatError ChatEvent -> ReaderT ChatController IO ()
toView_ Either ChatError ChatEvent
ev = do
  cc :: ChatController
cc@ChatController {outputQ :: ChatController -> TBQueue (Maybe Int64, Either ChatError ChatEvent)
outputQ = TBQueue (Maybe Int64, Either ChatError ChatEvent)
localQ, remoteCtrlSession :: ChatController -> TVar (Maybe (Int, RemoteCtrlSession))
remoteCtrlSession = TVar (Maybe (Int, RemoteCtrlSession))
session, config :: ChatController -> ChatConfig
config = ChatConfig {ChatHooks
chatHooks :: ChatConfig -> ChatHooks
chatHooks :: ChatHooks
chatHooks}} <- ReaderT ChatController IO ChatController
forall r (m :: * -> *). MonadReader r m => m r
ask
  Either ChatError ChatEvent
event <- case ChatHooks
-> Maybe
     (ChatController
      -> Either ChatError ChatEvent -> IO (Either ChatError ChatEvent))
eventHook ChatHooks
chatHooks of
    Just ChatController
-> Either ChatError ChatEvent -> IO (Either ChatError ChatEvent)
hook -> IO (Either ChatError ChatEvent)
-> ReaderT ChatController IO (Either ChatError ChatEvent)
forall a. IO a -> ReaderT ChatController IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Either ChatError ChatEvent)
 -> ReaderT ChatController IO (Either ChatError ChatEvent))
-> IO (Either ChatError ChatEvent)
-> ReaderT ChatController IO (Either ChatError ChatEvent)
forall a b. (a -> b) -> a -> b
$ ChatController
-> Either ChatError ChatEvent -> IO (Either ChatError ChatEvent)
hook ChatController
cc Either ChatError ChatEvent
ev
    Maybe
  (ChatController
   -> Either ChatError ChatEvent -> IO (Either ChatError ChatEvent))
Nothing -> Either ChatError ChatEvent
-> ReaderT ChatController IO (Either ChatError ChatEvent)
forall a. a -> ReaderT ChatController IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Either ChatError ChatEvent
ev
  STM () -> ReaderT ChatController IO ()
forall (m :: * -> *) a. MonadIO m => STM a -> m a
atomically (STM () -> ReaderT ChatController IO ())
-> STM () -> ReaderT ChatController IO ()
forall a b. (a -> b) -> a -> b
$
    TVar (Maybe (Int, RemoteCtrlSession))
-> STM (Maybe (Int, RemoteCtrlSession))
forall a. TVar a -> STM a
readTVar TVar (Maybe (Int, RemoteCtrlSession))
session STM (Maybe (Int, RemoteCtrlSession))
-> (Maybe (Int, RemoteCtrlSession) -> STM ()) -> STM ()
forall a b. STM a -> (a -> STM b) -> STM b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
      Just (Int
_, RCSessionConnected {TBQueue (Either ChatError ChatEvent)
remoteOutputQ :: RemoteCtrlSession -> TBQueue (Either ChatError ChatEvent)
remoteOutputQ :: TBQueue (Either ChatError ChatEvent)
remoteOutputQ})
        | (ChatError -> Bool)
-> (ChatEvent -> Bool) -> Either ChatError ChatEvent -> Bool
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (Bool -> ChatError -> Bool
forall a b. a -> b -> a
const Bool
True) ChatEvent -> Bool
allowRemoteEvent Either ChatError ChatEvent
event -> TBQueue (Either ChatError ChatEvent)
-> Either ChatError ChatEvent -> STM ()
forall a. TBQueue a -> a -> STM ()
writeTBQueue TBQueue (Either ChatError ChatEvent)
remoteOutputQ Either ChatError ChatEvent
event
      -- TODO potentially, it should hold some events while connecting
      Maybe (Int, RemoteCtrlSession)
_ -> TBQueue (Maybe Int64, Either ChatError ChatEvent)
-> (Maybe Int64, Either ChatError ChatEvent) -> STM ()
forall a. TBQueue a -> a -> STM ()
writeTBQueue TBQueue (Maybe Int64, Either ChatError ChatEvent)
localQ (Maybe Int64
forall a. Maybe a
Nothing, Either ChatError ChatEvent
event)

withStore' :: (DB.Connection -> IO a) -> CM a
withStore' :: forall a. (Connection -> IO a) -> CM a
withStore' Connection -> IO a
action = (Connection -> ExceptT StoreError IO a) -> CM a
forall a. (Connection -> ExceptT StoreError IO a) -> CM a
withStore ((Connection -> ExceptT StoreError IO a) -> CM a)
-> (Connection -> ExceptT StoreError IO a) -> CM a
forall a b. (a -> b) -> a -> b
$ IO a -> ExceptT StoreError IO a
forall a. IO a -> ExceptT StoreError IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO a -> ExceptT StoreError IO a)
-> (Connection -> IO a) -> Connection -> ExceptT StoreError IO a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Connection -> IO a
action
{-# INLINE withStore' #-}

withFastStore' :: (DB.Connection -> IO a) -> CM a
withFastStore' :: forall a. (Connection -> IO a) -> CM a
withFastStore' Connection -> IO a
action = (Connection -> ExceptT StoreError IO a) -> CM a
forall a. (Connection -> ExceptT StoreError IO a) -> CM a
withFastStore ((Connection -> ExceptT StoreError IO a) -> CM a)
-> (Connection -> ExceptT StoreError IO a) -> CM a
forall a b. (a -> b) -> a -> b
$ IO a -> ExceptT StoreError IO a
forall a. IO a -> ExceptT StoreError IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO a -> ExceptT StoreError IO a)
-> (Connection -> IO a) -> Connection -> ExceptT StoreError IO a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Connection -> IO a
action
{-# INLINE withFastStore' #-}

withStore :: (DB.Connection -> ExceptT StoreError IO a) -> CM a
withStore :: forall a. (Connection -> ExceptT StoreError IO a) -> CM a
withStore = Bool -> (Connection -> ExceptT StoreError IO a) -> CM a
forall a. Bool -> (Connection -> ExceptT StoreError IO a) -> CM a
withStorePriority Bool
False
{-# INLINE withStore #-}

withFastStore :: (DB.Connection -> ExceptT StoreError IO a) -> CM a
withFastStore :: forall a. (Connection -> ExceptT StoreError IO a) -> CM a
withFastStore = Bool -> (Connection -> ExceptT StoreError IO a) -> CM a
forall a. Bool -> (Connection -> ExceptT StoreError IO a) -> CM a
withStorePriority Bool
True
{-# INLINE withFastStore #-}

withStorePriority :: Bool -> (DB.Connection -> ExceptT StoreError IO a) -> CM a
withStorePriority :: forall a. Bool -> (Connection -> ExceptT StoreError IO a) -> CM a
withStorePriority Bool
priority Connection -> ExceptT StoreError IO a
action = do
  ChatController {DBStore
chatStore :: ChatController -> DBStore
chatStore :: DBStore
chatStore} <- ExceptT ChatError (ReaderT ChatController IO) ChatController
forall r (m :: * -> *). MonadReader r m => m r
ask
  IO (Either ChatError a) -> CM a
forall (m :: * -> *) e a.
(MonadIO m, MonadError e m) =>
IO (Either e a) -> m a
liftIOEither (IO (Either ChatError a) -> CM a)
-> IO (Either ChatError a) -> CM a
forall a b. (a -> b) -> a -> b
$ DBStore
-> Bool
-> (Connection -> IO (Either ChatError a))
-> IO (Either ChatError a)
forall a. DBStore -> Bool -> (Connection -> IO a) -> IO a
withTransactionPriority DBStore
chatStore Bool
priority (ExceptT ChatError IO a -> IO (Either ChatError a)
forall e (m :: * -> *) a. ExceptT e m a -> m (Either e a)
runExceptT (ExceptT ChatError IO a -> IO (Either ChatError a))
-> (Connection -> ExceptT ChatError IO a)
-> Connection
-> IO (Either ChatError a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (StoreError -> ChatError)
-> ExceptT StoreError IO a -> ExceptT ChatError IO a
forall (m :: * -> *) e e' a.
Functor m =>
(e -> e') -> ExceptT e m a -> ExceptT e' m a
withExceptT StoreError -> ChatError
ChatErrorStore (ExceptT StoreError IO a -> ExceptT ChatError IO a)
-> (Connection -> ExceptT StoreError IO a)
-> Connection
-> ExceptT ChatError IO a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Connection -> ExceptT StoreError IO a
action) IO (Either ChatError a)
-> [Handler (Either ChatError a)] -> IO (Either ChatError a)
forall a. IO a -> [Handler a] -> IO a
`E.catches` [Handler (Either ChatError a)]
forall a. [Handler (Either ChatError a)]
handleDBErrors

withStoreBatch :: Traversable t => (DB.Connection -> t (IO (Either ChatError a))) -> CM' (t (Either ChatError a))
withStoreBatch :: forall (t :: * -> *) a.
Traversable t =>
(Connection -> t (IO (Either ChatError a)))
-> CM' (t (Either ChatError a))
withStoreBatch Connection -> t (IO (Either ChatError a))
actions = do
  ChatController {DBStore
chatStore :: ChatController -> DBStore
chatStore :: DBStore
chatStore} <- ReaderT ChatController IO ChatController
forall r (m :: * -> *). MonadReader r m => m r
ask
  IO (t (Either ChatError a)) -> CM' (t (Either ChatError a))
forall a. IO a -> ReaderT ChatController IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (t (Either ChatError a)) -> CM' (t (Either ChatError a)))
-> IO (t (Either ChatError a)) -> CM' (t (Either ChatError a))
forall a b. (a -> b) -> a -> b
$ DBStore
-> (Connection -> IO (t (Either ChatError a)))
-> IO (t (Either ChatError a))
forall a. DBStore -> (Connection -> IO a) -> IO a
withTransaction DBStore
chatStore ((Connection -> IO (t (Either ChatError a)))
 -> IO (t (Either ChatError a)))
-> (Connection -> IO (t (Either ChatError a)))
-> IO (t (Either ChatError a))
forall a b. (a -> b) -> a -> b
$ (IO (Either ChatError a) -> IO (Either ChatError a))
-> t (IO (Either ChatError a)) -> IO (t (Either ChatError a))
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> t a -> m (t b)
mapM (IO (Either ChatError a)
-> [Handler (Either ChatError a)] -> IO (Either ChatError a)
forall a. IO a -> [Handler a] -> IO a
`E.catches` [Handler (Either ChatError a)]
forall a. [Handler (Either ChatError a)]
handleDBErrors) (t (IO (Either ChatError a)) -> IO (t (Either ChatError a)))
-> (Connection -> t (IO (Either ChatError a)))
-> Connection
-> IO (t (Either ChatError a))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Connection -> t (IO (Either ChatError a))
actions

-- TODO [postgres] postgres specific error handling
handleDBErrors :: [E.Handler (Either ChatError a)]
handleDBErrors :: forall a. [Handler (Either ChatError a)]
handleDBErrors =
#if !defined(dbPostgres)
  ( (SQLError -> IO (Either ChatError a))
-> Handler (Either ChatError a)
forall a e. Exception e => (e -> IO a) -> Handler a
E.Handler ((SQLError -> IO (Either ChatError a))
 -> Handler (Either ChatError a))
-> (SQLError -> IO (Either ChatError a))
-> Handler (Either ChatError a)
forall a b. (a -> b) -> a -> b
$ \(SQLError
e :: SQLError) ->
      let se :: Error
se = SQLError -> Error
SQL.sqlError SQLError
e
          busy :: Bool
busy = Error
se Error -> Error -> Bool
forall a. Eq a => a -> a -> Bool
== Error
SQL.ErrorBusy Bool -> Bool -> Bool
|| Error
se Error -> Error -> Bool
forall a. Eq a => a -> a -> Bool
== Error
SQL.ErrorLocked
       in Either ChatError a -> IO (Either ChatError a)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either ChatError a -> IO (Either ChatError a))
-> (StoreError -> Either ChatError a)
-> StoreError
-> IO (Either ChatError a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ChatError -> Either ChatError a
forall a b. a -> Either a b
Left (ChatError -> Either ChatError a)
-> (StoreError -> ChatError) -> StoreError -> Either ChatError a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StoreError -> ChatError
ChatErrorStore (StoreError -> IO (Either ChatError a))
-> StoreError -> IO (Either ChatError a)
forall a b. (a -> b) -> a -> b
$ if Bool
busy then [Char] -> StoreError
SEDBBusyError ([Char] -> StoreError) -> [Char] -> StoreError
forall a b. (a -> b) -> a -> b
$ Error -> [Char]
forall a. Show a => a -> [Char]
show Error
se else [Char] -> StoreError
SEDBException ([Char] -> StoreError) -> [Char] -> StoreError
forall a b. (a -> b) -> a -> b
$ SQLError -> [Char]
forall a. Show a => a -> [Char]
show SQLError
e
  ) Handler (Either ChatError a)
-> [Handler (Either ChatError a)] -> [Handler (Either ChatError a)]
forall a. a -> [a] -> [a]
:
#endif
  [ (SomeException -> IO (Either ChatError a))
-> Handler (Either ChatError a)
forall a e. Exception e => (e -> IO a) -> Handler a
E.Handler ((SomeException -> IO (Either ChatError a))
 -> Handler (Either ChatError a))
-> (SomeException -> IO (Either ChatError a))
-> Handler (Either ChatError a)
forall a b. (a -> b) -> a -> b
$ \(E.SomeException e
e) -> Either ChatError a -> IO (Either ChatError a)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either ChatError a -> IO (Either ChatError a))
-> ([Char] -> Either ChatError a)
-> [Char]
-> IO (Either ChatError a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ChatError -> Either ChatError a
forall a b. a -> Either a b
Left (ChatError -> Either ChatError a)
-> ([Char] -> ChatError) -> [Char] -> Either ChatError a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StoreError -> ChatError
ChatErrorStore (StoreError -> ChatError)
-> ([Char] -> StoreError) -> [Char] -> ChatError
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Char] -> StoreError
SEDBException ([Char] -> IO (Either ChatError a))
-> [Char] -> IO (Either ChatError a)
forall a b. (a -> b) -> a -> b
$ e -> [Char]
forall a. Show a => a -> [Char]
show e
e
  ]

withStoreBatch' :: Traversable t => (DB.Connection -> t (IO a)) -> CM' (t (Either ChatError a))
withStoreBatch' :: forall (t :: * -> *) a.
Traversable t =>
(Connection -> t (IO a)) -> CM' (t (Either ChatError a))
withStoreBatch' Connection -> t (IO a)
actions = (Connection -> t (IO (Either ChatError a)))
-> CM' (t (Either ChatError a))
forall (t :: * -> *) a.
Traversable t =>
(Connection -> t (IO (Either ChatError a)))
-> CM' (t (Either ChatError a))
withStoreBatch ((Connection -> t (IO (Either ChatError a)))
 -> CM' (t (Either ChatError a)))
-> (Connection -> t (IO (Either ChatError a)))
-> CM' (t (Either ChatError a))
forall a b. (a -> b) -> a -> b
$ (IO a -> IO (Either ChatError a))
-> t (IO a) -> t (IO (Either ChatError a))
forall a b. (a -> b) -> t a -> t b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((a -> Either ChatError a) -> IO a -> IO (Either ChatError a)
forall a b. (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> Either ChatError a
forall a b. b -> Either a b
Right) (t (IO a) -> t (IO (Either ChatError a)))
-> (Connection -> t (IO a))
-> Connection
-> t (IO (Either ChatError a))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Connection -> t (IO a)
actions

withAgent :: (AgentClient -> ExceptT AgentErrorType IO a) -> CM a
withAgent :: forall a. (AgentClient -> ExceptT AgentErrorType IO a) -> CM a
withAgent AgentClient -> ExceptT AgentErrorType IO a
action =
  (ChatController -> AgentClient)
-> ExceptT ChatError (ReaderT ChatController IO) AgentClient
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks ChatController -> AgentClient
smpAgent
    ExceptT ChatError (ReaderT ChatController IO) AgentClient
-> (AgentClient
    -> ExceptT
         ChatError (ReaderT ChatController IO) (Either AgentErrorType a))
-> ExceptT
     ChatError (ReaderT ChatController IO) (Either AgentErrorType a)
forall a b.
ExceptT ChatError (ReaderT ChatController IO) a
-> (a -> ExceptT ChatError (ReaderT ChatController IO) b)
-> ExceptT ChatError (ReaderT ChatController IO) b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= IO (Either AgentErrorType a)
-> ExceptT
     ChatError (ReaderT ChatController IO) (Either AgentErrorType a)
forall a. IO a -> ExceptT ChatError (ReaderT ChatController IO) a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Either AgentErrorType a)
 -> ExceptT
      ChatError (ReaderT ChatController IO) (Either AgentErrorType a))
-> (AgentClient -> IO (Either AgentErrorType a))
-> AgentClient
-> ExceptT
     ChatError (ReaderT ChatController IO) (Either AgentErrorType a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ExceptT AgentErrorType IO a -> IO (Either AgentErrorType a)
forall e (m :: * -> *) a. ExceptT e m a -> m (Either e a)
runExceptT (ExceptT AgentErrorType IO a -> IO (Either AgentErrorType a))
-> (AgentClient -> ExceptT AgentErrorType IO a)
-> AgentClient
-> IO (Either AgentErrorType a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AgentClient -> ExceptT AgentErrorType IO a
action
    ExceptT
  ChatError (ReaderT ChatController IO) (Either AgentErrorType a)
-> (Either AgentErrorType a
    -> ExceptT ChatError (ReaderT ChatController IO) a)
-> ExceptT ChatError (ReaderT ChatController IO) a
forall a b.
ExceptT ChatError (ReaderT ChatController IO) a
-> (a -> ExceptT ChatError (ReaderT ChatController IO) b)
-> ExceptT ChatError (ReaderT ChatController IO) b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Either ChatError a
-> ExceptT ChatError (ReaderT ChatController IO) a
forall e (m :: * -> *) a. MonadError e m => Either e a -> m a
liftEither (Either ChatError a
 -> ExceptT ChatError (ReaderT ChatController IO) a)
-> (Either AgentErrorType a -> Either ChatError a)
-> Either AgentErrorType a
-> ExceptT ChatError (ReaderT ChatController IO) a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (AgentErrorType -> ChatError)
-> Either AgentErrorType a -> Either ChatError a
forall a b c. (a -> b) -> Either a c -> Either b c
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first (\AgentErrorType
e -> AgentErrorType
-> AgentConnId -> Maybe ConnectionEntity -> ChatError
ChatErrorAgent AgentErrorType
e (MsgId -> AgentConnId
AgentConnId MsgId
"") Maybe ConnectionEntity
forall a. Maybe a
Nothing)

withAgent' :: (AgentClient -> IO a) -> CM' a
withAgent' :: forall a. (AgentClient -> IO a) -> CM' a
withAgent' AgentClient -> IO a
action = (ChatController -> AgentClient)
-> ReaderT ChatController IO AgentClient
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks ChatController -> AgentClient
smpAgent ReaderT ChatController IO AgentClient
-> (AgentClient -> ReaderT ChatController IO a)
-> ReaderT ChatController IO a
forall a b.
ReaderT ChatController IO a
-> (a -> ReaderT ChatController IO b)
-> ReaderT ChatController IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= IO a -> ReaderT ChatController IO a
forall a. IO a -> ReaderT ChatController IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO a -> ReaderT ChatController IO a)
-> (AgentClient -> IO a)
-> AgentClient
-> ReaderT ChatController IO a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AgentClient -> IO a
action

$(JQ.deriveJSON (enumJSON $ dropPrefix "HS") ''HelpSection)

$(JQ.deriveJSON (sumTypeJSON $ dropPrefix "CLQ") ''ChatListQuery)

$(JQ.deriveJSON (sumTypeJSON $ dropPrefix "ILP") ''InvitationLinkPlan)

$(JQ.deriveJSON (sumTypeJSON $ dropPrefix "CAP") ''ContactAddressPlan)

$(JQ.deriveJSON (sumTypeJSON $ dropPrefix "GLP") ''GroupLinkPlan)

$(JQ.deriveJSON (sumTypeJSON $ dropPrefix "FC") ''ForwardConfirmation)

$(JQ.deriveJSON (sumTypeJSON $ dropPrefix "CE") ''ChatErrorType)

$(JQ.deriveJSON (sumTypeJSON $ dropPrefix "RHE") ''RemoteHostError)

$(JQ.deriveJSON (sumTypeJSON $ dropPrefix "RCE") ''RemoteCtrlError)

$(JQ.deriveJSON (sumTypeJSON $ dropPrefix "SQLite") ''SQLiteError)

$(JQ.deriveJSON (sumTypeJSON $ dropPrefix "DB") ''DatabaseError)

$(JQ.deriveJSON (sumTypeJSON $ dropPrefix "Chat") ''ChatError)

$(JQ.deriveJSON (sumTypeJSON $ dropPrefix "CP") ''ConnectionPlan)

$(JQ.deriveJSON defaultJSON ''AppFilePathsConfig)

$(JQ.deriveJSON defaultJSON ''ConnSubResult)

$(JQ.deriveJSON (sumTypeJSON $ dropPrefix "AE") ''ArchiveError)

$(JQ.deriveJSON defaultJSON ''UserProfileUpdateSummary)

$(JQ.deriveJSON defaultJSON ''NtfMsgInfo)

$(JQ.deriveJSON (sumTypeJSON $ dropPrefix "RNM") ''RcvNtfMsgInfo)

$(JQ.deriveJSON defaultJSON ''NtfConn)

$(JQ.deriveJSON defaultJSON ''NtfMsgAckInfo)

$(JQ.deriveJSON defaultJSON ''SwitchProgress)

$(JQ.deriveJSON defaultJSON ''RatchetSyncProgress)

$(JQ.deriveJSON defaultJSON ''DeletedRcvQueue)

$(JQ.deriveJSON defaultJSON ''ServerAddress)

$(JQ.deriveJSON defaultJSON ''ParsedServerAddress)

$(JQ.deriveJSON defaultJSON ''ChatItemDeletion)

$(JQ.deriveJSON defaultJSON ''CoreVersionInfo)

#if !defined(dbPostgres)
$(JQ.deriveJSON defaultJSON ''SlowSQLQuery)
#endif

$(JQ.deriveJSON (sumTypeJSON $ dropPrefix "RCS") ''RemoteCtrlSessionState)

$(JQ.deriveJSON defaultJSON ''RemoteCtrlInfo)

$(JQ.deriveJSON (sumTypeJSON $ dropPrefix "RCSR") ''RemoteCtrlStopReason)

$(JQ.deriveJSON (sumTypeJSON $ dropPrefix "RHSR") ''RemoteHostStopReason)

$(JQ.deriveJSON (sumTypeJSON $ dropPrefix "TE") ''TerminalEvent)

$(JQ.deriveJSON (sumTypeJSON $ dropPrefix "CR") ''ChatResponse)

$(JQ.deriveJSON (sumTypeJSON $ dropPrefix "CEvt") ''ChatEvent)

$(JQ.deriveFromJSON defaultJSON ''ArchiveConfig)

$(JQ.deriveFromJSON defaultJSON ''DBEncryptionConfig)

$(JQ.deriveToJSON defaultJSON ''ComposedMessage)

instance FromJSON ComposedMessage where
  parseJSON :: Value -> Parser ComposedMessage
parseJSON (J.Object Object
v) = do
    Maybe CryptoFile
fileSource <-
      (Object
v Object -> Key -> Parser (Maybe CryptoFile)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"fileSource") Parser (Maybe CryptoFile)
-> (Maybe CryptoFile -> Parser (Maybe CryptoFile))
-> Parser (Maybe CryptoFile)
forall a b. Parser a -> (a -> Parser b) -> Parser b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
        Maybe CryptoFile
Nothing -> [Char] -> CryptoFile
CF.plain ([Char] -> CryptoFile)
-> Parser (Maybe [Char]) -> Parser (Maybe CryptoFile)
forall (f :: * -> *) (g :: * -> *) a b.
(Functor f, Functor g) =>
(a -> b) -> f (g a) -> f (g b)
<$$> (Object
v Object -> Key -> Parser (Maybe [Char])
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"filePath")
        Maybe CryptoFile
f -> Maybe CryptoFile -> Parser (Maybe CryptoFile)
forall a. a -> Parser a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe CryptoFile
f
    Maybe Int64
quotedItemId <- Object
v Object -> Key -> Parser (Maybe Int64)
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"quotedItemId"
    MsgContent
msgContent <- Object
v Object -> Key -> Parser MsgContent
forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"msgContent"
    Map Text Int64
mentions <- Map Text Int64 -> Maybe (Map Text Int64) -> Map Text Int64
forall a. a -> Maybe a -> a
fromMaybe Map Text Int64
forall k a. Map k a
M.empty (Maybe (Map Text Int64) -> Map Text Int64)
-> Parser (Maybe (Map Text Int64)) -> Parser (Map Text Int64)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
v Object -> Key -> Parser (Maybe (Map Text Int64))
forall a. FromJSON a => Object -> Key -> Parser (Maybe a)
.:? Key
"mentions"
    ComposedMessage -> Parser ComposedMessage
forall a. a -> Parser a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ComposedMessage {Maybe CryptoFile
fileSource :: Maybe CryptoFile
fileSource :: Maybe CryptoFile
fileSource, Maybe Int64
quotedItemId :: Maybe Int64
quotedItemId :: Maybe Int64
quotedItemId, MsgContent
msgContent :: MsgContent
msgContent :: MsgContent
msgContent, Map Text Int64
mentions :: Map Text Int64
mentions :: Map Text Int64
mentions}
  parseJSON Value
invalid =
    [Char] -> Parser ComposedMessage -> Parser ComposedMessage
forall a. [Char] -> Parser a -> Parser a
JT.prependFailure [Char]
"bad ComposedMessage, " ([Char] -> Value -> Parser ComposedMessage
forall a. [Char] -> Value -> Parser a
JT.typeMismatch [Char]
"Object" Value
invalid)

$(JQ.deriveJSON defaultJSON ''UpdatedMessage)

$(JQ.deriveToJSON defaultJSON ''ChatTagData)