{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TemplateHaskell #-}
{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-}

{-# HLINT ignore "Use newtype instead of data" #-}

module Simplex.Chat.Call where

import Data.Aeson (FromJSON (..), ToJSON (..))
import qualified Data.Aeson.TH as J
import qualified Data.Attoparsec.ByteString.Char8 as A
import Data.ByteString.Char8 (ByteString)
import Data.Int (Int64)
import Data.Text (Text)
import Data.Time.Clock (UTCTime)
import Simplex.Chat.Options.DB (FromField (..), ToField (..))
import Simplex.Chat.Types (Contact, ContactId, User)
import Simplex.Messaging.Agent.Store.DB (Binary (..), fromTextField_)
import qualified Simplex.Messaging.Crypto as C
import Simplex.Messaging.Encoding.String
import Simplex.Messaging.Parsers (defaultJSON, dropPrefix, enumJSON, fstToLower, singleFieldJSON)
import Simplex.Messaging.Util (decodeJSON, encodeJSON)

data Call = Call
  { Call -> ContactId
contactId :: ContactId,
    Call -> CallId
callId :: CallId,
    Call -> Text
callUUID :: Text,
    Call -> ContactId
chatItemId :: Int64,
    Call -> CallState
callState :: CallState,
    Call -> UTCTime
callTs :: UTCTime
  }
  deriving (Int -> Call -> ShowS
[Call] -> ShowS
Call -> String
(Int -> Call -> ShowS)
-> (Call -> String) -> ([Call] -> ShowS) -> Show Call
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Call -> ShowS
showsPrec :: Int -> Call -> ShowS
$cshow :: Call -> String
show :: Call -> String
$cshowList :: [Call] -> ShowS
showList :: [Call] -> ShowS
Show)

isRcvInvitation :: Call -> Bool
isRcvInvitation :: Call -> Bool
isRcvInvitation Call {CallState
callState :: Call -> CallState
callState :: CallState
callState} = case CallState
callState of
  CallInvitationReceived {} -> Bool
True
  CallState
_ -> Bool
False

data CallStateTag
  = CSTCallInvitationSent
  | CSTCallInvitationReceived
  | CSTCallOfferSent
  | CSTCallOfferReceived
  | CSTCallNegotiated
  deriving (Int -> CallStateTag -> ShowS
[CallStateTag] -> ShowS
CallStateTag -> String
(Int -> CallStateTag -> ShowS)
-> (CallStateTag -> String)
-> ([CallStateTag] -> ShowS)
-> Show CallStateTag
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> CallStateTag -> ShowS
showsPrec :: Int -> CallStateTag -> ShowS
$cshow :: CallStateTag -> String
show :: CallStateTag -> String
$cshowList :: [CallStateTag] -> ShowS
showList :: [CallStateTag] -> ShowS
Show)

callStateTag :: CallState -> CallStateTag
callStateTag :: CallState -> CallStateTag
callStateTag = \case
  CallInvitationSent {} -> CallStateTag
CSTCallInvitationSent
  CallInvitationReceived {} -> CallStateTag
CSTCallInvitationReceived
  CallOfferSent {} -> CallStateTag
CSTCallOfferSent
  CallOfferReceived {} -> CallStateTag
CSTCallOfferReceived
  CallNegotiated {} -> CallStateTag
CSTCallNegotiated

data CallState
  = CallInvitationSent
      { CallState -> CallType
localCallType :: CallType,
        CallState -> Maybe PrivateKeyX25519
localDhPrivKey :: Maybe C.PrivateKeyX25519
      }
  | CallInvitationReceived
      { CallState -> CallType
peerCallType :: CallType,
        CallState -> Maybe PublicKeyX25519
localDhPubKey :: Maybe C.PublicKeyX25519,
        CallState -> Maybe Key
sharedKey :: Maybe C.Key
      }
  | CallOfferSent
      { localCallType :: CallType,
        peerCallType :: CallType,
        CallState -> WebRTCSession
localCallSession :: WebRTCSession,
        sharedKey :: Maybe C.Key
      }
  | CallOfferReceived
      { localCallType :: CallType,
        peerCallType :: CallType,
        CallState -> WebRTCSession
peerCallSession :: WebRTCSession,
        sharedKey :: Maybe C.Key
      }
  | CallNegotiated
      { localCallType :: CallType,
        peerCallType :: CallType,
        localCallSession :: WebRTCSession,
        peerCallSession :: WebRTCSession,
        sharedKey :: Maybe C.Key
      }
  deriving (Int -> CallState -> ShowS
[CallState] -> ShowS
CallState -> String
(Int -> CallState -> ShowS)
-> (CallState -> String)
-> ([CallState] -> ShowS)
-> Show CallState
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> CallState -> ShowS
showsPrec :: Int -> CallState -> ShowS
$cshow :: CallState -> String
show :: CallState -> String
$cshowList :: [CallState] -> ShowS
showList :: [CallState] -> ShowS
Show)

newtype CallId = CallId ByteString
  deriving (CallId -> CallId -> Bool
(CallId -> CallId -> Bool)
-> (CallId -> CallId -> Bool) -> Eq CallId
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: CallId -> CallId -> Bool
== :: CallId -> CallId -> Bool
$c/= :: CallId -> CallId -> Bool
/= :: CallId -> CallId -> Bool
Eq, Int -> CallId -> ShowS
[CallId] -> ShowS
CallId -> String
(Int -> CallId -> ShowS)
-> (CallId -> String) -> ([CallId] -> ShowS) -> Show CallId
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> CallId -> ShowS
showsPrec :: Int -> CallId -> ShowS
$cshow :: CallId -> String
show :: CallId -> String
$cshowList :: [CallId] -> ShowS
showList :: [CallId] -> ShowS
Show)
  deriving newtype (FieldParser CallId
FieldParser CallId -> FromField CallId
forall a. FieldParser a -> FromField a
$cfromField :: FieldParser CallId
fromField :: FieldParser CallId
FromField)

instance ToField CallId where toField :: CallId -> SQLData
toField (CallId ByteString
m) = Binary ByteString -> SQLData
forall a. ToField a => a -> SQLData
toField (Binary ByteString -> SQLData) -> Binary ByteString -> SQLData
forall a b. (a -> b) -> a -> b
$ ByteString -> Binary ByteString
forall a. a -> Binary a
Binary ByteString
m

instance StrEncoding CallId where
  strEncode :: CallId -> ByteString
strEncode (CallId ByteString
m) = ByteString -> ByteString
forall a. StrEncoding a => a -> ByteString
strEncode ByteString
m
  strDecode :: ByteString -> Either String CallId
strDecode ByteString
s = ByteString -> CallId
CallId (ByteString -> CallId)
-> Either String ByteString -> Either String CallId
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ByteString -> Either String ByteString
forall a. StrEncoding a => ByteString -> Either String a
strDecode ByteString
s
  strP :: Parser CallId
strP = ByteString -> CallId
CallId (ByteString -> CallId)
-> Parser ByteString ByteString -> Parser CallId
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser ByteString ByteString
forall a. StrEncoding a => Parser a
strP

instance FromJSON CallId where
  parseJSON :: Value -> Parser CallId
parseJSON = String -> Value -> Parser CallId
forall a. StrEncoding a => String -> Value -> Parser a
strParseJSON String
"CallId"

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

data RcvCallInvitation = RcvCallInvitation
  { RcvCallInvitation -> User
user :: User,
    RcvCallInvitation -> Contact
contact :: Contact,
    RcvCallInvitation -> CallType
callType :: CallType,
    RcvCallInvitation -> Maybe Key
sharedKey :: Maybe C.Key,
    RcvCallInvitation -> Text
callUUID :: Text,
    RcvCallInvitation -> UTCTime
callTs :: UTCTime
  }
  deriving (Int -> RcvCallInvitation -> ShowS
[RcvCallInvitation] -> ShowS
RcvCallInvitation -> String
(Int -> RcvCallInvitation -> ShowS)
-> (RcvCallInvitation -> String)
-> ([RcvCallInvitation] -> ShowS)
-> Show RcvCallInvitation
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> RcvCallInvitation -> ShowS
showsPrec :: Int -> RcvCallInvitation -> ShowS
$cshow :: RcvCallInvitation -> String
show :: RcvCallInvitation -> String
$cshowList :: [RcvCallInvitation] -> ShowS
showList :: [RcvCallInvitation] -> ShowS
Show)

data CallType = CallType
  { CallType -> CallMedia
media :: CallMedia,
    CallType -> CallCapabilities
capabilities :: CallCapabilities
  }
  deriving (CallType -> CallType -> Bool
(CallType -> CallType -> Bool)
-> (CallType -> CallType -> Bool) -> Eq CallType
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: CallType -> CallType -> Bool
== :: CallType -> CallType -> Bool
$c/= :: CallType -> CallType -> Bool
/= :: CallType -> CallType -> Bool
Eq, Int -> CallType -> ShowS
[CallType] -> ShowS
CallType -> String
(Int -> CallType -> ShowS)
-> (CallType -> String) -> ([CallType] -> ShowS) -> Show CallType
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> CallType -> ShowS
showsPrec :: Int -> CallType -> ShowS
$cshow :: CallType -> String
show :: CallType -> String
$cshowList :: [CallType] -> ShowS
showList :: [CallType] -> ShowS
Show)

defaultCallType :: CallType
defaultCallType :: CallType
defaultCallType = CallMedia -> CallCapabilities -> CallType
CallType CallMedia
CMVideo (CallCapabilities -> CallType) -> CallCapabilities -> CallType
forall a b. (a -> b) -> a -> b
$ CallCapabilities {encryption :: Bool
encryption = Bool
True}

encryptedCall :: CallType -> Bool
encryptedCall :: CallType -> Bool
encryptedCall CallType {capabilities :: CallType -> CallCapabilities
capabilities = CallCapabilities {Bool
encryption :: CallCapabilities -> Bool
encryption :: Bool
encryption}} = Bool
encryption

-- | * Types for chat protocol
data CallInvitation = CallInvitation
  { CallInvitation -> CallType
callType :: CallType,
    CallInvitation -> Maybe PublicKeyX25519
callDhPubKey :: Maybe C.PublicKeyX25519
  }
  deriving (CallInvitation -> CallInvitation -> Bool
(CallInvitation -> CallInvitation -> Bool)
-> (CallInvitation -> CallInvitation -> Bool) -> Eq CallInvitation
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: CallInvitation -> CallInvitation -> Bool
== :: CallInvitation -> CallInvitation -> Bool
$c/= :: CallInvitation -> CallInvitation -> Bool
/= :: CallInvitation -> CallInvitation -> Bool
Eq, Int -> CallInvitation -> ShowS
[CallInvitation] -> ShowS
CallInvitation -> String
(Int -> CallInvitation -> ShowS)
-> (CallInvitation -> String)
-> ([CallInvitation] -> ShowS)
-> Show CallInvitation
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> CallInvitation -> ShowS
showsPrec :: Int -> CallInvitation -> ShowS
$cshow :: CallInvitation -> String
show :: CallInvitation -> String
$cshowList :: [CallInvitation] -> ShowS
showList :: [CallInvitation] -> ShowS
Show)

data CallMedia = CMAudio | CMVideo
  deriving (CallMedia -> CallMedia -> Bool
(CallMedia -> CallMedia -> Bool)
-> (CallMedia -> CallMedia -> Bool) -> Eq CallMedia
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: CallMedia -> CallMedia -> Bool
== :: CallMedia -> CallMedia -> Bool
$c/= :: CallMedia -> CallMedia -> Bool
/= :: CallMedia -> CallMedia -> Bool
Eq, Int -> CallMedia -> ShowS
[CallMedia] -> ShowS
CallMedia -> String
(Int -> CallMedia -> ShowS)
-> (CallMedia -> String)
-> ([CallMedia] -> ShowS)
-> Show CallMedia
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> CallMedia -> ShowS
showsPrec :: Int -> CallMedia -> ShowS
$cshow :: CallMedia -> String
show :: CallMedia -> String
$cshowList :: [CallMedia] -> ShowS
showList :: [CallMedia] -> ShowS
Show)

data CallCapabilities = CallCapabilities
  { CallCapabilities -> Bool
encryption :: Bool
  }
  deriving (CallCapabilities -> CallCapabilities -> Bool
(CallCapabilities -> CallCapabilities -> Bool)
-> (CallCapabilities -> CallCapabilities -> Bool)
-> Eq CallCapabilities
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: CallCapabilities -> CallCapabilities -> Bool
== :: CallCapabilities -> CallCapabilities -> Bool
$c/= :: CallCapabilities -> CallCapabilities -> Bool
/= :: CallCapabilities -> CallCapabilities -> Bool
Eq, Int -> CallCapabilities -> ShowS
[CallCapabilities] -> ShowS
CallCapabilities -> String
(Int -> CallCapabilities -> ShowS)
-> (CallCapabilities -> String)
-> ([CallCapabilities] -> ShowS)
-> Show CallCapabilities
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> CallCapabilities -> ShowS
showsPrec :: Int -> CallCapabilities -> ShowS
$cshow :: CallCapabilities -> String
show :: CallCapabilities -> String
$cshowList :: [CallCapabilities] -> ShowS
showList :: [CallCapabilities] -> ShowS
Show)

data CallOffer = CallOffer
  { CallOffer -> CallType
callType :: CallType,
    CallOffer -> WebRTCSession
rtcSession :: WebRTCSession,
    CallOffer -> Maybe PublicKeyX25519
callDhPubKey :: Maybe C.PublicKeyX25519
  }
  deriving (CallOffer -> CallOffer -> Bool
(CallOffer -> CallOffer -> Bool)
-> (CallOffer -> CallOffer -> Bool) -> Eq CallOffer
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: CallOffer -> CallOffer -> Bool
== :: CallOffer -> CallOffer -> Bool
$c/= :: CallOffer -> CallOffer -> Bool
/= :: CallOffer -> CallOffer -> Bool
Eq, Int -> CallOffer -> ShowS
[CallOffer] -> ShowS
CallOffer -> String
(Int -> CallOffer -> ShowS)
-> (CallOffer -> String)
-> ([CallOffer] -> ShowS)
-> Show CallOffer
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> CallOffer -> ShowS
showsPrec :: Int -> CallOffer -> ShowS
$cshow :: CallOffer -> String
show :: CallOffer -> String
$cshowList :: [CallOffer] -> ShowS
showList :: [CallOffer] -> ShowS
Show)

data WebRTCCallOffer = WebRTCCallOffer
  { WebRTCCallOffer -> CallType
callType :: CallType,
    WebRTCCallOffer -> WebRTCSession
rtcSession :: WebRTCSession
  }
  deriving (WebRTCCallOffer -> WebRTCCallOffer -> Bool
(WebRTCCallOffer -> WebRTCCallOffer -> Bool)
-> (WebRTCCallOffer -> WebRTCCallOffer -> Bool)
-> Eq WebRTCCallOffer
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: WebRTCCallOffer -> WebRTCCallOffer -> Bool
== :: WebRTCCallOffer -> WebRTCCallOffer -> Bool
$c/= :: WebRTCCallOffer -> WebRTCCallOffer -> Bool
/= :: WebRTCCallOffer -> WebRTCCallOffer -> Bool
Eq, Int -> WebRTCCallOffer -> ShowS
[WebRTCCallOffer] -> ShowS
WebRTCCallOffer -> String
(Int -> WebRTCCallOffer -> ShowS)
-> (WebRTCCallOffer -> String)
-> ([WebRTCCallOffer] -> ShowS)
-> Show WebRTCCallOffer
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> WebRTCCallOffer -> ShowS
showsPrec :: Int -> WebRTCCallOffer -> ShowS
$cshow :: WebRTCCallOffer -> String
show :: WebRTCCallOffer -> String
$cshowList :: [WebRTCCallOffer] -> ShowS
showList :: [WebRTCCallOffer] -> ShowS
Show)

data CallAnswer = CallAnswer
  { CallAnswer -> WebRTCSession
rtcSession :: WebRTCSession
  }
  deriving (CallAnswer -> CallAnswer -> Bool
(CallAnswer -> CallAnswer -> Bool)
-> (CallAnswer -> CallAnswer -> Bool) -> Eq CallAnswer
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: CallAnswer -> CallAnswer -> Bool
== :: CallAnswer -> CallAnswer -> Bool
$c/= :: CallAnswer -> CallAnswer -> Bool
/= :: CallAnswer -> CallAnswer -> Bool
Eq, Int -> CallAnswer -> ShowS
[CallAnswer] -> ShowS
CallAnswer -> String
(Int -> CallAnswer -> ShowS)
-> (CallAnswer -> String)
-> ([CallAnswer] -> ShowS)
-> Show CallAnswer
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> CallAnswer -> ShowS
showsPrec :: Int -> CallAnswer -> ShowS
$cshow :: CallAnswer -> String
show :: CallAnswer -> String
$cshowList :: [CallAnswer] -> ShowS
showList :: [CallAnswer] -> ShowS
Show)

data CallExtraInfo = CallExtraInfo
  { CallExtraInfo -> WebRTCExtraInfo
rtcExtraInfo :: WebRTCExtraInfo
  }
  deriving (CallExtraInfo -> CallExtraInfo -> Bool
(CallExtraInfo -> CallExtraInfo -> Bool)
-> (CallExtraInfo -> CallExtraInfo -> Bool) -> Eq CallExtraInfo
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: CallExtraInfo -> CallExtraInfo -> Bool
== :: CallExtraInfo -> CallExtraInfo -> Bool
$c/= :: CallExtraInfo -> CallExtraInfo -> Bool
/= :: CallExtraInfo -> CallExtraInfo -> Bool
Eq, Int -> CallExtraInfo -> ShowS
[CallExtraInfo] -> ShowS
CallExtraInfo -> String
(Int -> CallExtraInfo -> ShowS)
-> (CallExtraInfo -> String)
-> ([CallExtraInfo] -> ShowS)
-> Show CallExtraInfo
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> CallExtraInfo -> ShowS
showsPrec :: Int -> CallExtraInfo -> ShowS
$cshow :: CallExtraInfo -> String
show :: CallExtraInfo -> String
$cshowList :: [CallExtraInfo] -> ShowS
showList :: [CallExtraInfo] -> ShowS
Show)

data WebRTCSession = WebRTCSession
  { WebRTCSession -> Text
rtcSession :: Text, -- LZW compressed JSON encoding of offer or answer
    WebRTCSession -> Text
rtcIceCandidates :: Text -- LZW compressed JSON encoding of array of ICE candidates
  }
  deriving (WebRTCSession -> WebRTCSession -> Bool
(WebRTCSession -> WebRTCSession -> Bool)
-> (WebRTCSession -> WebRTCSession -> Bool) -> Eq WebRTCSession
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: WebRTCSession -> WebRTCSession -> Bool
== :: WebRTCSession -> WebRTCSession -> Bool
$c/= :: WebRTCSession -> WebRTCSession -> Bool
/= :: WebRTCSession -> WebRTCSession -> Bool
Eq, Int -> WebRTCSession -> ShowS
[WebRTCSession] -> ShowS
WebRTCSession -> String
(Int -> WebRTCSession -> ShowS)
-> (WebRTCSession -> String)
-> ([WebRTCSession] -> ShowS)
-> Show WebRTCSession
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> WebRTCSession -> ShowS
showsPrec :: Int -> WebRTCSession -> ShowS
$cshow :: WebRTCSession -> String
show :: WebRTCSession -> String
$cshowList :: [WebRTCSession] -> ShowS
showList :: [WebRTCSession] -> ShowS
Show)

data WebRTCExtraInfo = WebRTCExtraInfo
  { WebRTCExtraInfo -> Text
rtcIceCandidates :: Text -- LZW compressed JSON encoding of array of ICE candidates
  }
  deriving (WebRTCExtraInfo -> WebRTCExtraInfo -> Bool
(WebRTCExtraInfo -> WebRTCExtraInfo -> Bool)
-> (WebRTCExtraInfo -> WebRTCExtraInfo -> Bool)
-> Eq WebRTCExtraInfo
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: WebRTCExtraInfo -> WebRTCExtraInfo -> Bool
== :: WebRTCExtraInfo -> WebRTCExtraInfo -> Bool
$c/= :: WebRTCExtraInfo -> WebRTCExtraInfo -> Bool
/= :: WebRTCExtraInfo -> WebRTCExtraInfo -> Bool
Eq, Int -> WebRTCExtraInfo -> ShowS
[WebRTCExtraInfo] -> ShowS
WebRTCExtraInfo -> String
(Int -> WebRTCExtraInfo -> ShowS)
-> (WebRTCExtraInfo -> String)
-> ([WebRTCExtraInfo] -> ShowS)
-> Show WebRTCExtraInfo
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> WebRTCExtraInfo -> ShowS
showsPrec :: Int -> WebRTCExtraInfo -> ShowS
$cshow :: WebRTCExtraInfo -> String
show :: WebRTCExtraInfo -> String
$cshowList :: [WebRTCExtraInfo] -> ShowS
showList :: [WebRTCExtraInfo] -> ShowS
Show)

data WebRTCCallStatus = WCSConnecting | WCSConnected | WCSDisconnected | WCSFailed
  deriving (Int -> WebRTCCallStatus -> ShowS
[WebRTCCallStatus] -> ShowS
WebRTCCallStatus -> String
(Int -> WebRTCCallStatus -> ShowS)
-> (WebRTCCallStatus -> String)
-> ([WebRTCCallStatus] -> ShowS)
-> Show WebRTCCallStatus
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> WebRTCCallStatus -> ShowS
showsPrec :: Int -> WebRTCCallStatus -> ShowS
$cshow :: WebRTCCallStatus -> String
show :: WebRTCCallStatus -> String
$cshowList :: [WebRTCCallStatus] -> ShowS
showList :: [WebRTCCallStatus] -> ShowS
Show)

instance StrEncoding WebRTCCallStatus where
  strEncode :: WebRTCCallStatus -> ByteString
strEncode = \case
    WebRTCCallStatus
WCSConnecting -> ByteString
"connecting"
    WebRTCCallStatus
WCSConnected -> ByteString
"connected"
    WebRTCCallStatus
WCSDisconnected -> ByteString
"disconnected"
    WebRTCCallStatus
WCSFailed -> ByteString
"failed"
  strP :: Parser WebRTCCallStatus
strP =
    (Char -> Bool) -> Parser ByteString ByteString
A.takeTill (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
' ') Parser ByteString ByteString
-> (ByteString -> Parser WebRTCCallStatus)
-> Parser WebRTCCallStatus
forall a b.
Parser ByteString a
-> (a -> Parser ByteString b) -> Parser ByteString b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
      ByteString
"connecting" -> WebRTCCallStatus -> Parser WebRTCCallStatus
forall a. a -> Parser ByteString a
forall (f :: * -> *) a. Applicative f => a -> f a
pure WebRTCCallStatus
WCSConnecting
      ByteString
"connected" -> WebRTCCallStatus -> Parser WebRTCCallStatus
forall a. a -> Parser ByteString a
forall (f :: * -> *) a. Applicative f => a -> f a
pure WebRTCCallStatus
WCSConnected
      ByteString
"disconnected" -> WebRTCCallStatus -> Parser WebRTCCallStatus
forall a. a -> Parser ByteString a
forall (f :: * -> *) a. Applicative f => a -> f a
pure WebRTCCallStatus
WCSDisconnected
      ByteString
"failed" -> WebRTCCallStatus -> Parser WebRTCCallStatus
forall a. a -> Parser ByteString a
forall (f :: * -> *) a. Applicative f => a -> f a
pure WebRTCCallStatus
WCSFailed
      ByteString
_ -> String -> Parser WebRTCCallStatus
forall a. String -> Parser ByteString a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"bad WebRTCCallStatus"

$(J.deriveJSON (enumJSON $ dropPrefix "CSTCall") ''CallStateTag)

$(J.deriveJSON (enumJSON $ dropPrefix "CM") ''CallMedia)

$(J.deriveJSON defaultJSON ''CallCapabilities)

$(J.deriveJSON defaultJSON ''CallType)

$(J.deriveJSON defaultJSON ''CallInvitation)

$(J.deriveJSON defaultJSON ''WebRTCSession)

$(J.deriveJSON defaultJSON ''CallOffer)

$(J.deriveJSON defaultJSON ''WebRTCCallOffer)

$(J.deriveJSON defaultJSON ''CallAnswer)

$(J.deriveJSON defaultJSON ''WebRTCExtraInfo)

$(J.deriveJSON defaultJSON ''CallExtraInfo)

-- database representation
$(J.deriveJSON (singleFieldJSON fstToLower) ''CallState)

instance ToField CallState where
  toField :: CallState -> SQLData
toField = Text -> SQLData
forall a. ToField a => a -> SQLData
toField (Text -> SQLData) -> (CallState -> Text) -> CallState -> SQLData
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CallState -> Text
forall a. ToJSON a => a -> Text
encodeJSON

instance FromField CallState where
  fromField :: FieldParser CallState
fromField = (Text -> Maybe CallState) -> FieldParser CallState
forall a. Typeable a => (Text -> Maybe a) -> Field -> Ok a
fromTextField_ Text -> Maybe CallState
forall a. FromJSON a => Text -> Maybe a
decodeJSON

$(J.deriveJSON defaultJSON ''RcvCallInvitation)