{-# OPTIONS_HADDOCK hide, prune, ignore-exports #-}

module Tesla.Internal.HTTP where

import           Control.Lens
import           Control.Monad.IO.Class (MonadIO (..))
import           Data.Aeson             (FromJSON (..))
import qualified Data.ByteString.Char8  as BC
import           Network.Wreq           (Options, asJSON, defaults, get, getWith, header, postWith, responseBody)
import           Network.Wreq.Types     (Postable)

import           Tesla.Auth

userAgent :: BC.ByteString
userAgent :: ByteString
userAgent = ByteString
"github.com/dustin/tesla 0.1"

defOpts :: Options
defOpts :: Options
defOpts = Options
defaults forall a b. a -> (a -> b) -> b
& HeaderName -> Lens' Options [ByteString]
header HeaderName
"User-Agent" forall s t a b. ASetter s t a b -> b -> s -> t
.~ [ByteString
userAgent]

-- | Get a set of wreq options from an 'AuthInfo'.
authOpts :: AuthInfo -> Options
authOpts :: AuthInfo -> Options
authOpts AuthInfo{String
_bearerToken :: AuthInfo -> String
_password :: AuthInfo -> String
_email :: AuthInfo -> String
_clientSecret :: AuthInfo -> String
_clientID :: AuthInfo -> String
_bearerToken :: String
_password :: String
_email :: String
_clientSecret :: String
_clientID :: String
..} = Options
defOpts forall a b. a -> (a -> b) -> b
& HeaderName -> Lens' Options [ByteString]
header HeaderName
"Authorization" forall s t a b. ASetter s t a b -> b -> s -> t
.~ [ByteString
"Bearer " forall a. Semigroup a => a -> a -> a
<> String -> ByteString
BC.pack String
_bearerToken]

jget :: (FromJSON j, MonadIO m) => String -> m j
jget :: forall j (m :: * -> *). (FromJSON j, MonadIO m) => String -> m j
jget String
u = forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view forall body0 body1.
Lens (Response body0) (Response body1) body0 body1
responseBody forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (forall (m :: * -> *) a.
(MonadThrow m, FromJSON a) =>
Response ByteString -> m (Response a)
asJSON forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< String -> IO (Response ByteString)
get String
u)

jgetWith :: (FromJSON j, MonadIO m) => Options -> String -> m j
jgetWith :: forall j (m :: * -> *).
(FromJSON j, MonadIO m) =>
Options -> String -> m j
jgetWith Options
opts String
u = forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view forall body0 body1.
Lens (Response body0) (Response body1) body0 body1
responseBody forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (forall (m :: * -> *) a.
(MonadThrow m, FromJSON a) =>
Response ByteString -> m (Response a)
asJSON forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Options -> String -> IO (Response ByteString)
getWith Options
opts String
u)

jgetAuth :: (HasTeslaAuth m, FromJSON j, MonadIO m) => String -> m j
jgetAuth :: forall (m :: * -> *) j.
(HasTeslaAuth m, FromJSON j, MonadIO m) =>
String -> m j
jgetAuth String
u = forall (m :: * -> *). HasTeslaAuth m => m AuthInfo
teslaAuth forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \AuthInfo
a -> forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view forall body0 body1.
Lens (Response body0) (Response body1) body0 body1
responseBody forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (forall (m :: * -> *) a.
(MonadThrow m, FromJSON a) =>
Response ByteString -> m (Response a)
asJSON forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Options -> String -> IO (Response ByteString)
getWith (AuthInfo -> Options
authOpts AuthInfo
a) String
u)

jpostWith :: (FromJSON j, Postable a, MonadIO m) => Options -> String -> a -> m j
jpostWith :: forall j a (m :: * -> *).
(FromJSON j, Postable a, MonadIO m) =>
Options -> String -> a -> m j
jpostWith Options
opts String
u a
v = forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view forall body0 body1.
Lens (Response body0) (Response body1) body0 body1
responseBody forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (forall a.
Postable a =>
Options -> String -> a -> IO (Response ByteString)
postWith Options
opts String
u a
v forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall (m :: * -> *) a.
(MonadThrow m, FromJSON a) =>
Response ByteString -> m (Response a)
asJSON)

jpostAuth :: (HasTeslaAuth m, FromJSON j, Postable a, MonadIO m) => String -> a -> m j
jpostAuth :: forall (m :: * -> *) j a.
(HasTeslaAuth m, FromJSON j, Postable a, MonadIO m) =>
String -> a -> m j
jpostAuth String
u a
v = forall (m :: * -> *). HasTeslaAuth m => m AuthInfo
teslaAuth forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \AuthInfo
a -> forall j a (m :: * -> *).
(FromJSON j, Postable a, MonadIO m) =>
Options -> String -> a -> m j
jpostWith (AuthInfo -> Options
authOpts AuthInfo
a forall a b. a -> (a -> b) -> b
& HeaderName -> Lens' Options [ByteString]
header HeaderName
"Content-Type" forall s t a b. ASetter s t a b -> b -> s -> t
.~ [ByteString
"application/json"]) String
u a
v