-- |
-- Module      : Network.Pusher.Internal
-- Description : Pure functions called by the public interface
-- Copyright   : (c) Will Sewell, 2016
-- Licence     : MIT
-- Maintainer  : me@willsewell.com
-- Stability   : stable
module Network.Pusher.Internal
  ( mkTriggerRequest,
    mkTriggerBatchRequest,
    mkChannelsRequest,
    mkChannelRequest,
    mkUsersRequest,
  )
where

import qualified Data.Aeson as A
import qualified Data.ByteString as B
import qualified Data.ByteString.Lazy as BL
import Data.Maybe (maybeToList)
import qualified Data.Text as T
import Data.Text.Encoding (encodeUtf8)
import Data.Word (Word64)
import Network.HTTP.Types (Query)
import Network.Pusher.Data (Event, Pusher (..))
import Network.Pusher.Internal.Auth (makeQS)
import Network.Pusher.Internal.HTTP
  ( RequestParams (RequestParams),
  )
import Network.Pusher.Protocol
  ( ChannelInfoQuery,
    ChannelsInfoQuery,
    toURLParam,
  )

mkTriggerRequest ::
  Pusher ->
  [T.Text] ->
  T.Text ->
  T.Text ->
  Maybe T.Text ->
  Word64 ->
  (RequestParams, A.Value)
mkTriggerRequest :: Pusher
-> [Text]
-> Text
-> Text
-> Maybe Text
-> Word64
-> (RequestParams, Value)
mkTriggerRequest Pusher
pusher [Text]
channels Text
event Text
dat Maybe Text
socketId Word64
timestamp =
  let body :: Value
body =
        [Pair] -> Value
A.object forall a b. (a -> b) -> a -> b
$
          [ (Key
"name", Text -> Value
A.String Text
event),
            (Key
"channels", forall a. ToJSON a => a -> Value
A.toJSON (forall a b. (a -> b) -> [a] -> [b]
map Text -> Value
A.String [Text]
channels)),
            (Key
"data", Text -> Value
A.String Text
dat)
          ]
            forall a. [a] -> [a] -> [a]
++ forall a. Maybe a -> [a]
maybeToList (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\Text
sID -> (Key
"socket_id", Text -> Value
A.String Text
sID)) Maybe Text
socketId)
      bodyBS :: ByteString
bodyBS = ByteString -> ByteString
BL.toStrict forall a b. (a -> b) -> a -> b
$ forall a. ToJSON a => a -> ByteString
A.encode Value
body
   in (Pusher
-> ByteString -> Query -> ByteString -> Word64 -> RequestParams
mkPostRequest Pusher
pusher ByteString
"events" [] ByteString
bodyBS Word64
timestamp, Value
body)

mkTriggerBatchRequest ::
  Pusher ->
  [Event] ->
  Word64 ->
  (RequestParams, A.Value)
mkTriggerBatchRequest :: Pusher -> [Event] -> Word64 -> (RequestParams, Value)
mkTriggerBatchRequest Pusher
pusher [Event]
events Word64
timestamp =
  let body :: Value
body = [Pair] -> Value
A.object [(Key
"batch", forall a. ToJSON a => a -> Value
A.toJSON [Event]
events)]
      bodyBS :: ByteString
bodyBS = ByteString -> ByteString
BL.toStrict forall a b. (a -> b) -> a -> b
$ forall a. ToJSON a => a -> ByteString
A.encode Value
body
   in (Pusher
-> ByteString -> Query -> ByteString -> Word64 -> RequestParams
mkPostRequest Pusher
pusher ByteString
"batch_events" [] ByteString
bodyBS Word64
timestamp, Value
body)

mkChannelsRequest ::
  Pusher ->
  T.Text ->
  ChannelsInfoQuery ->
  Word64 ->
  RequestParams
mkChannelsRequest :: Pusher -> Text -> ChannelsInfoQuery -> Word64 -> RequestParams
mkChannelsRequest Pusher
pusher Text
prefixFilter ChannelsInfoQuery
attributes Word64
timestamp =
  let params :: Query
params =
        [ (ByteString
"info", forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ Text -> ByteString
encodeUtf8 forall a b. (a -> b) -> a -> b
$ forall a. ToURLParam a => a -> Text
toURLParam ChannelsInfoQuery
attributes),
          (ByteString
"filter_by_prefix", forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ Text -> ByteString
encodeUtf8 Text
prefixFilter)
        ]
   in Pusher -> ByteString -> Query -> Word64 -> RequestParams
mkGetRequest Pusher
pusher ByteString
"channels" Query
params Word64
timestamp

mkChannelRequest ::
  Pusher -> B.ByteString -> ChannelInfoQuery -> Word64 -> RequestParams
mkChannelRequest :: Pusher -> ByteString -> ChannelInfoQuery -> Word64 -> RequestParams
mkChannelRequest Pusher
pusher ByteString
chan ChannelInfoQuery
attributes Word64
timestamp =
  let params :: Query
params = [(ByteString
"info", forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ Text -> ByteString
encodeUtf8 forall a b. (a -> b) -> a -> b
$ forall a. ToURLParam a => a -> Text
toURLParam ChannelInfoQuery
attributes)]
      subPath :: ByteString
subPath = ByteString
"channels/" forall a. Semigroup a => a -> a -> a
<> ByteString
chan
   in Pusher -> ByteString -> Query -> Word64 -> RequestParams
mkGetRequest Pusher
pusher ByteString
subPath Query
params Word64
timestamp

mkUsersRequest :: Pusher -> B.ByteString -> Word64 -> RequestParams
mkUsersRequest :: Pusher -> ByteString -> Word64 -> RequestParams
mkUsersRequest Pusher
pusher ByteString
chan Word64
timestamp =
  let subPath :: ByteString
subPath = ByteString
"channels/" forall a. Semigroup a => a -> a -> a
<> ByteString
chan forall a. Semigroup a => a -> a -> a
<> ByteString
"/users"
   in Pusher -> ByteString -> Query -> Word64 -> RequestParams
mkGetRequest Pusher
pusher ByteString
subPath [] Word64
timestamp

mkGetRequest ::
  Pusher ->
  B.ByteString ->
  Query ->
  Word64 ->
  RequestParams
mkGetRequest :: Pusher -> ByteString -> Query -> Word64 -> RequestParams
mkGetRequest Pusher
pusher ByteString
subPath Query
params = Pusher
-> ByteString
-> ByteString
-> Query
-> ByteString
-> Word64
-> RequestParams
mkRequest Pusher
pusher ByteString
"GET" ByteString
subPath Query
params ByteString
""

mkPostRequest ::
  Pusher ->
  B.ByteString ->
  Query ->
  B.ByteString ->
  Word64 ->
  RequestParams
mkPostRequest :: Pusher
-> ByteString -> Query -> ByteString -> Word64 -> RequestParams
mkPostRequest Pusher
pusher = Pusher
-> ByteString
-> ByteString
-> Query
-> ByteString
-> Word64
-> RequestParams
mkRequest Pusher
pusher ByteString
"POST"

mkRequest ::
  Pusher ->
  B.ByteString ->
  B.ByteString ->
  Query ->
  B.ByteString ->
  Word64 ->
  RequestParams
mkRequest :: Pusher
-> ByteString
-> ByteString
-> Query
-> ByteString
-> Word64
-> RequestParams
mkRequest Pusher
pusher ByteString
method ByteString
subPath Query
params ByteString
bodyBS Word64
timestamp =
  let useTLS :: Bool
useTLS = Pusher -> Bool
pUseTLS Pusher
pusher
      host :: ByteString
host = Pusher -> ByteString
pHost Pusher
pusher
      port :: Word16
port = Pusher -> Word16
pPort Pusher
pusher
      path :: ByteString
path = Pusher -> ByteString
pPath Pusher
pusher forall a. Semigroup a => a -> a -> a
<> ByteString
subPath
      qs :: Query
qs = Token
-> ByteString
-> ByteString
-> Query
-> ByteString
-> Word64
-> Query
makeQS (Pusher -> Token
pToken Pusher
pusher) ByteString
method ByteString
path Query
params ByteString
bodyBS Word64
timestamp
   in Bool
-> ByteString -> Word16 -> ByteString -> Query -> RequestParams
RequestParams Bool
useTLS ByteString
host Word16
port ByteString
path Query
qs