-- 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.2.0.1


-- | 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 ()


-- | 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.
data 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 ChannelInfoAttributes.
newtype ChannelInfoQuery
ChannelInfoQuery :: (HashSet ChannelInfoAttributes) -> ChannelInfoQuery

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

-- | A set of requested ChannelsInfoAttributes.
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.
data 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

-- | Convert the data into a querystring parameter value.
toURLParam :: ToURLParam a => a -> Text

-- | Convert the data into a querystring parameter value.
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 Network.Pusher.Protocol.ToURLParam Network.Pusher.Protocol.ChannelsInfoAttributes
instance Data.Hashable.Class.Hashable Network.Pusher.Protocol.ChannelsInfoAttributes
instance Network.Pusher.Protocol.ToURLParam Network.Pusher.Protocol.ChannelInfoAttributes
instance Data.Hashable.Class.Hashable Network.Pusher.Protocol.ChannelInfoAttributes
instance Network.Pusher.Protocol.ToURLParam a => Network.Pusher.Protocol.ToURLParam (Data.HashSet.HashSet a)
instance Data.Aeson.Types.FromJSON.FromJSON Network.Pusher.Protocol.ChannelsInfo
instance Data.Aeson.Types.FromJSON.FromJSON Network.Pusher.Protocol.ChannelInfo
instance Data.Aeson.Types.FromJSON.FromJSON Network.Pusher.Protocol.FullChannelInfo
instance Data.Aeson.Types.FromJSON.FromJSON Network.Pusher.Protocol.Users
instance Data.Aeson.Types.FromJSON.FromJSON Network.Pusher.Protocol.User


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


-- | 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 = Credentials
--       { credentialsAppID = 123
--       , credentialsAppKey = wrd12344rcd234
--       , credentialsAppSecret = 124df34d545v
--       }
--   pusher &lt;- getPusher credentials
--   result &lt;-
--     trigger pusher [Channel Public "my-channel"] "my-event" "my-data" Nothing
--   case result of
--     Left e -&gt; error e
--     Right resp -&gt; print resp
--   </pre>
--   
--   There is a simple working example 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 -> Credentials -> Manager -> Pusher
[pusherHost] :: Pusher -> Text
[pusherPath] :: Pusher -> Text
[pusherCredentials] :: Pusher -> Credentials
[pusherConnectionManager] :: Pusher -> Manager

-- | The credentials for the current app.
data Credentials
Credentials :: AppID -> AppKey -> AppSecret -> Credentials
[credentialsAppID] :: Credentials -> AppID
[credentialsAppKey] :: Credentials -> AppKey
[credentialsAppSecret] :: Credentials -> AppSecret
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 -> 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 -> 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

-- | 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)

-- | 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
