-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Haskell client library for the Pusher HTTP API
--   
--   Functions that correspond to endpoints of the Pusher HTTP API.
--   Messages can be triggered, and information about the channel can be
--   queried. Additionally there are functions for authenticating users of
--   private and presence channels.
@package pusher-http-haskell
@version 1.5.1.5


-- | A layer on top of the HTTP functions in the Wreq library which lifts
--   the return values to the typclasses we are using in this library. Non
--   200 responses are converted into MonadError errors.
module Network.Pusher.Internal.HTTP
data RequestParams
RequestParams :: Text -> RequestQueryString -> RequestParams

-- | The API endpoint, for example
--   <a>http://api.pusherapp.com/apps/123/events</a>.
[requestEndpoint] :: RequestParams -> Text

-- | List of query string parameters as key-value tuples.
[requestQueryString] :: RequestParams -> RequestQueryString
type RequestQueryString = [(ByteString, ByteString)]
type RequestBody = Value

-- | Issue an HTTP GET request. On a 200 response, the response body is
--   returned. On failure, an error will be thrown into the MonadError
--   instance.
get :: FromJSON a => Manager -> RequestParams -> ExceptT PusherError IO a

-- | Issue an HTTP POST request.
post :: ToJSON a => Manager -> RequestParams -> a -> ExceptT PusherError IO ()
instance GHC.Show.Show Network.Pusher.Internal.HTTP.RequestParams


-- | This module contains helper functions for authenticating HTTP
--   requests, as well as publically facing functions for authentication
--   private and presence channel users; these functions are re-exported in
--   the main Pusher module.
module Network.Pusher.Internal.Auth

-- | The bytestring to sign with the app secret to create a signature from.
type AuthString = ByteString

-- | A Pusher auth signature.
type AuthSignature = ByteString

-- | Generate an auth signature of the form "app_key:auth_sig" for a user
--   of a presence channel.
authenticatePresence :: ToJSON a => Credentials -> SocketID -> Channel -> a -> AuthSignature

-- | As above, but allows the encoder of the user data to be specified.
--   This is useful for testing because the encoder can be mocked; aeson's
--   encoder enodes JSON object fields in arbitrary orders, which makes it
--   impossible to test.
authenticatePresenceWithEncoder :: (a -> Text) -> Credentials -> SocketID -> Channel -> a -> AuthSignature

-- | Generate an auth signature of the form "app_key:auth_sig" for a user
--   of a private channel.
authenticatePrivate :: Credentials -> SocketID -> Channel -> AuthSignature

-- | Generate the required query string parameters required to send API
--   requests to Pusher.
makeQS :: AppKey -> AppSecret -> Text -> Text -> RequestQueryString -> ByteString -> Int -> RequestQueryString


-- | Types representing the JSON format of Pusher messages.
--   
--   There are also types for query string parameters.
module Network.Pusher.Protocol

-- | The possible returned channel attributes when multiple when multiple
--   channels are queried.
newtype ChannelInfo
ChannelInfo :: Maybe Int -> ChannelInfo
[channelInfoUserCount] :: ChannelInfo -> Maybe Int

-- | Enumeration of the attributes that can be queried about a single
--   channel.
data ChannelInfoAttributes
ChannelUserCount :: ChannelInfoAttributes
ChannelSubscriptionCount :: ChannelInfoAttributes

-- | A set of requested <a>ChannelInfoAttributes</a>.
newtype ChannelInfoQuery
ChannelInfoQuery :: (HashSet ChannelInfoAttributes) -> ChannelInfoQuery

-- | A map of channels to their <a>ChannelInfo</a>. The result of querying
--   channel info from multuple channels.
newtype ChannelsInfo
ChannelsInfo :: (HashMap Channel ChannelInfo) -> ChannelsInfo

-- | A set of requested <a>ChannelsInfoAttributes</a>.
newtype ChannelsInfoQuery
ChannelsInfoQuery :: (HashSet ChannelsInfoAttributes) -> ChannelsInfoQuery

-- | Enumeration of the attributes that can be queried about multiple
--   channels.
data ChannelsInfoAttributes
ChannelsUserCount :: ChannelsInfoAttributes

-- | The possible values returned by a query to a single channel.
data FullChannelInfo
FullChannelInfo :: Bool -> Maybe Int -> Maybe Int -> FullChannelInfo
[fullChannelInfoOccupied] :: FullChannelInfo -> Bool
[fullChannelInfoUserCount] :: FullChannelInfo -> Maybe Int
[fullChannelInfoSubCount] :: FullChannelInfo -> Maybe Int

-- | The data about a user returned when querying for users in a presence
--   channel.
newtype User
User :: Text -> User
[userID] :: User -> Text

-- | A list of users returned by querying for users in a presence channel.
newtype Users
Users :: [User] -> Users

-- | Types that can be serialised to a querystring parameter value.
class ToURLParam a
toURLParam :: ToURLParam a => a -> Text
toURLParam :: ToURLParam a => a -> Text
instance GHC.Show.Show Network.Pusher.Protocol.Users
instance GHC.Classes.Eq Network.Pusher.Protocol.Users
instance GHC.Show.Show Network.Pusher.Protocol.User
instance GHC.Classes.Eq Network.Pusher.Protocol.User
instance GHC.Show.Show Network.Pusher.Protocol.FullChannelInfo
instance GHC.Classes.Eq Network.Pusher.Protocol.FullChannelInfo
instance GHC.Show.Show Network.Pusher.Protocol.ChannelsInfo
instance GHC.Classes.Eq Network.Pusher.Protocol.ChannelsInfo
instance GHC.Show.Show Network.Pusher.Protocol.ChannelInfo
instance GHC.Classes.Eq Network.Pusher.Protocol.ChannelInfo
instance Network.Pusher.Protocol.ToURLParam Network.Pusher.Protocol.ChannelInfoQuery
instance GHC.Generics.Generic Network.Pusher.Protocol.ChannelInfoAttributes
instance GHC.Classes.Eq Network.Pusher.Protocol.ChannelInfoAttributes
instance Network.Pusher.Protocol.ToURLParam Network.Pusher.Protocol.ChannelsInfoQuery
instance GHC.Generics.Generic Network.Pusher.Protocol.ChannelsInfoAttributes
instance GHC.Classes.Eq Network.Pusher.Protocol.ChannelsInfoAttributes
instance Data.Aeson.Types.FromJSON.FromJSON Network.Pusher.Protocol.Users
instance Data.Aeson.Types.FromJSON.FromJSON Network.Pusher.Protocol.User
instance Data.Aeson.Types.FromJSON.FromJSON Network.Pusher.Protocol.FullChannelInfo
instance Data.Aeson.Types.FromJSON.FromJSON Network.Pusher.Protocol.ChannelsInfo
instance Data.Aeson.Types.FromJSON.FromJSON Network.Pusher.Protocol.ChannelInfo
instance Network.Pusher.Protocol.ToURLParam Network.Pusher.Protocol.ChannelInfoAttributes
instance Data.Hashable.Class.Hashable Network.Pusher.Protocol.ChannelInfoAttributes
instance Network.Pusher.Protocol.ToURLParam Network.Pusher.Protocol.ChannelsInfoAttributes
instance Data.Hashable.Class.Hashable Network.Pusher.Protocol.ChannelsInfoAttributes
instance Network.Pusher.Protocol.ToURLParam a => Network.Pusher.Protocol.ToURLParam (Data.HashSet.HashSet a)


module Network.Pusher.Internal
mkTriggerRequest :: Pusher -> [Channel] -> Event -> EventData -> Maybe SocketID -> Int -> Either PusherError (RequestParams, RequestBody)
mkChannelsRequest :: Pusher -> Maybe ChannelType -> Text -> ChannelsInfoQuery -> Int -> RequestParams
mkChannelRequest :: Pusher -> Channel -> ChannelInfoQuery -> Int -> RequestParams
mkUsersRequest :: Pusher -> Channel -> Int -> RequestParams
mkNotifyRequest :: Pusher -> Notification -> Int -> Either PusherError (RequestParams, RequestBody)


-- | Exposes the functions necessary for interacting with the Pusher HTTP
--   API, as well as functions for generating auth signatures for private
--   and presence channels.
--   
--   First create a <a>Pusher</a> data structure with your Pusher
--   <a>Credentials</a>, and then call the functions defined in this module
--   to make the HTTP requests.
--   
--   If any of the requests fail, the return values of the functions will
--   result in a <a>Left</a> <a>PusherError</a> when run.
--   
--   An example of how you would use these functions:
--   
--   <pre>
--   let
--     credentials = <a>Credentials</a>
--       { <a>credentialsAppID</a>     = 123
--       , <a>credentialsAppKey</a>    = "wrd12344rcd234"
--       , <a>credentialsAppSecret</a> = "124df34d545v"
--       , <a>credentialsCluster</a>   = Nothing
--       }
--   pusher &lt;- <a>getPusher</a> credentials
--   
--   triggerRes &lt;-
--     <a>trigger</a> pusher [<a>Channel</a> <a>Public</a> "my-channel"] "my-event" "my-data" Nothing
--   
--   case triggerRes of
--     Left e -&gt; putStrLn $ displayException e
--     Right resp -&gt; print resp
--   
--   -- import qualified Data.HashMap.Strict as H
--   -- import qualified Data.Aeson          as A
--   let
--     -- A Firebase Cloud Messaging notification payload
--     fcmObject = H.fromList [("notification", A.Object $ H.fromList
--                                 [("title", A.String "a title")
--                                 ,("body" , A.String "some text")
--                                 ,("icon" , A.String "logo.png")
--                                 ]
--                             )]
--     Just interest = <a>mkInterest</a> "some-interest"
--   
--     -- A Pusher notification
--     notification = <a>Notification</a>
--       { <a>notificationInterest</a>     = interest
--       , <a>notificationWebhookURL</a>   = Nothing
--       , <a>notificationWebhookLevel</a> = Nothing
--       , <a>notificationAPNSPayload</a>  = Nothing
--       , <a>notificationGCMPayload</a>   = Nothing
--       , <a>notificationFCMPayload</a>   = Just $ <a>FCMPayload</a> fcmObject
--       }
--   
--   notifyRes &lt;- <a>notify</a> pusher notification
--   </pre>
--   
--   There are simple working examples in the example/ directory.
--   
--   See <a>https://pusher.com/docs/rest_api</a> for more detail on the
--   HTTP requests.
module Network.Pusher

-- | All the required configuration needed to interact with the API.
data Pusher
Pusher :: Text -> Text -> Text -> Text -> Credentials -> Manager -> Pusher
[pusherHost] :: Pusher -> Text
[pusherPath] :: Pusher -> Text
[pusherNotifyHost] :: Pusher -> Text
[pusherNotifyPath] :: Pusher -> Text
[pusherCredentials] :: Pusher -> Credentials
[pusherConnectionManager] :: Pusher -> Manager

-- | The credentials for the current app.
data Credentials
Credentials :: AppID -> AppKey -> AppSecret -> Maybe Cluster -> Credentials
[credentialsAppID] :: Credentials -> AppID
[credentialsAppKey] :: Credentials -> AppKey
[credentialsAppSecret] :: Credentials -> AppSecret
[credentialsCluster] :: Credentials -> Maybe Cluster

-- | The cluster the current app resides on. Common clusters include:
--   mt1,eu,ap1,ap2.
newtype Cluster
Cluster :: Text -> Cluster
[clusterName] :: Cluster -> Text
type AppID = Integer
type AppKey = ByteString
type AppSecret = ByteString

-- | Use this to get an instance Pusher. This will fill in the host and
--   path automatically.
getPusher :: MonadIO m => Credentials -> m Pusher

-- | Get a Pusher instance that uses a specific API endpoint.
getPusherWithHost :: MonadIO m => Text -> Text -> Credentials -> m Pusher

-- | Get a Pusher instance with a given connection manager. This can be
--   useful if you want to share a connection with your application code.
getPusherWithConnManager :: Manager -> Maybe Text -> Maybe Text -> Credentials -> Pusher

-- | The channel name (not including the channel type prefix) and its type.
data Channel
Channel :: ChannelType -> ChannelName -> Channel
[channelType] :: Channel -> ChannelType
[channelName] :: Channel -> ChannelName
type ChannelName = Text

-- | The possible types of Pusher channe.
data ChannelType
Public :: ChannelType
Private :: ChannelType
Presence :: ChannelType
renderChannel :: Channel -> Text
renderChannelPrefix :: ChannelType -> Text

-- | Convert string representation, e.g. private-chan into the datatype.
parseChannel :: Text -> Channel
type Event = Text
type EventData = Text
type SocketID = Text
data Notification
Notification :: Interest -> Maybe WebhookURL -> Maybe WebhookLevel -> Maybe APNSPayload -> Maybe GCMPayload -> Maybe FCMPayload -> Notification
[notificationInterest] :: Notification -> Interest
[notificationWebhookURL] :: Notification -> Maybe WebhookURL
[notificationWebhookLevel] :: Notification -> Maybe WebhookLevel
[notificationAPNSPayload] :: Notification -> Maybe APNSPayload
[notificationGCMPayload] :: Notification -> Maybe GCMPayload
[notificationFCMPayload] :: Notification -> Maybe FCMPayload

-- | Up to 164 characters where each character is ASCII upper or lower
--   case, a number or one of _=@,.;
--   
--   Note: hyphen - is NOT valid as it is reserved for the possibility of
--   marking interest names with prefixes such as private- or presence-.
data Interest
mkInterest :: Text -> Maybe Interest

-- | URL to which pusher will send information about sent push
--   notifications.
type WebhookURL = Text

-- | Level of detail sent to WebhookURL. Defaults to Info.
data WebhookLevel

-- | Errors only
Info :: WebhookLevel

-- | Everything
Debug :: WebhookLevel

-- | Apple push notification service payload.
data APNSPayload
APNSPayload :: Object -> APNSPayload

-- | Google Cloud Messaging payload.
data GCMPayload
GCMPayload :: Object -> GCMPayload

-- | Firebase Cloud Messaging payload.
data FCMPayload
FCMPayload :: Object -> FCMPayload

-- | Trigger an event to one or more channels.
trigger :: MonadIO m => Pusher -> [Channel] -> Event -> EventData -> Maybe SocketID -> m (Either PusherError ())

-- | Query a list of channels for information.
channels :: MonadIO m => Pusher -> Maybe ChannelType -> Text -> ChannelsInfoQuery -> m (Either PusherError ChannelsInfo)

-- | Query for information on a single channel.
channel :: MonadIO m => Pusher -> Channel -> ChannelInfoQuery -> m (Either PusherError FullChannelInfo)

-- | Get a list of users in a presence channel.
users :: MonadIO m => Pusher -> Channel -> m (Either PusherError Users)

-- | Send a push notification.
notify :: MonadIO m => Pusher -> Notification -> m (Either PusherError ())

-- | The bytestring to sign with the app secret to create a signature from.
type AuthString = ByteString

-- | A Pusher auth signature.
type AuthSignature = ByteString

-- | Generate an auth signature of the form "app_key:auth_sig" for a user
--   of a presence channel.
authenticatePresence :: ToJSON a => Credentials -> SocketID -> Channel -> a -> AuthSignature

-- | Generate an auth signature of the form "app_key:auth_sig" for a user
--   of a private channel.
authenticatePrivate :: Credentials -> SocketID -> Channel -> AuthSignature
data PusherError

-- | Data from the caller is not valid.
PusherArgumentError :: Text -> PusherError

-- | Received non 200 response code from Pusher.
PusherNon200ResponseError :: Text -> PusherError

-- | Received unexpected data from Pusher.
PusherInvalidResponseError :: Text -> PusherError

-- | Parse webhooks from a list of HTTP headers and a HTTP body given their
--   <a>AppKey</a> matches the one in our Pusher credentials and the
--   webhook is correctly encrypted by the corresponding <a>AppSecret</a>.
parseWebhookPayload :: Pusher -> [(ByteString, ByteString)] -> ByteString -> Maybe WebhookPayload

-- | A <a>WebhookEv</a> is one of several events Pusher may send to your
--   server in response to events your users may trigger.
data WebhookEv

-- | A channel has become occupied. There is &gt; 1 subscriber.
ChannelOccupiedEv :: Channel -> WebhookEv
[onChannel] :: WebhookEv -> Channel

-- | A channel has become vacated. There are 0 subscribers.
ChannelVacatedEv :: Channel -> WebhookEv
[onChannel] :: WebhookEv -> Channel

-- | A new user has subscribed to a presence channel.
MemberAddedEv :: Channel -> User -> WebhookEv
[onChannel] :: WebhookEv -> Channel
[withUser] :: WebhookEv -> User

-- | A user has unsubscribed from a presence channel.
MemberRemovedEv :: Channel -> User -> WebhookEv
[onChannel] :: WebhookEv -> Channel
[withUser] :: WebhookEv -> User

-- | A client has sent a named client event with some json body. They have
--   a <a>SocketID</a> and a <a>User</a> if they were in a presence
--   channel.
ClientEv :: Channel -> Text -> Maybe Value -> SocketID -> Maybe User -> WebhookEv
[onChannel] :: WebhookEv -> Channel
[clientEvName] :: WebhookEv -> Text
[clientEvBody] :: WebhookEv -> Maybe Value
[withSocketId] :: WebhookEv -> SocketID
[withPossibleUser] :: WebhookEv -> Maybe User
data WebhookPayload
WebhookPayload :: AppKey -> AuthSignature -> Webhooks -> WebhookPayload

-- | Authentication header. The oldest active token is used, identified by
--   this key.
[xPusherKey] :: WebhookPayload -> AppKey

-- | A HMAC SHA256 formed by signing the payload with the tokens secret.
[xPusherSignature] :: WebhookPayload -> AuthSignature
[webhooks] :: WebhookPayload -> Webhooks

-- | A Webhook is received by POST request from Pusher to notify your
--   server of a number of <a>WebhookEv</a>s. Multiple events are received
--   under the same timestamp if batch events is enabled.
data Webhooks
Webhooks :: UTCTime -> [WebhookEv] -> Webhooks
[timeMs] :: Webhooks -> UTCTime
[webhookEvs] :: Webhooks -> [WebhookEv]

-- | Given a HTTP Header and its associated value, parse an <a>AppKey</a>.
parseAppKeyHdr :: ByteString -> ByteString -> Maybe AppKey

-- | Given a HTTP Header and its associated value, parse a
--   <a>AuthSignature</a>.
parseAuthSignatureHdr :: ByteString -> ByteString -> Maybe AuthSignature

-- | Given a HTTP body, parse the contained webhooks.
parseWebhooksBody :: ByteString -> Maybe Webhooks

-- | Does a webhook body hash with our secret key to the given signature?
verifyWebhooksBody :: AppSecret -> AuthSignature -> ByteString -> Bool

-- | Given a list of http header key:values, a http body and a lookup
--   function for an apps secret, parse and validate a potential webhook
--   payload.
parseWebhookPayloadWith :: (AppKey -> Maybe AppSecret) -> [(ByteString, ByteString)] -> ByteString -> Maybe WebhookPayload
