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

module GoPro.Plus.Internal.HTTP where

import           Control.Lens
import           Control.Monad.IO.Class (MonadIO (..))
import           Data.Aeson             (FromJSON (..), Options (..), defaultOptions, fieldLabelModifier)
import qualified Data.ByteString.Char8  as BC
import qualified Data.ByteString.Lazy   as BL
import           Data.Text              (Text)
import qualified Data.Text.Encoding     as TE
import           Network.Wreq           (Options, asJSON, defaults, getWith, header, postWith, responseBody)
import           Network.Wreq.Types     (Postable)

userAgent :: BC.ByteString
userAgent :: ByteString
userAgent = ByteString
"github.com/dustin/gopro-plus 0.6.0.3"

defOpts :: Network.Wreq.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]
          forall a b. a -> (a -> b) -> b
& HeaderName -> Lens' Options [ByteString]
header HeaderName
"Referer" forall s t a b. ASetter s t a b -> b -> s -> t
.~ [ByteString
"https://plus.gopro.com/"]
          forall a b. a -> (a -> b) -> b
& HeaderName -> Lens' Options [ByteString]
header HeaderName
"Origin" forall s t a b. ASetter s t a b -> b -> s -> t
.~ [ByteString
"https://plus.gopro.com"]
          forall a b. a -> (a -> b) -> b
& HeaderName -> Lens' Options [ByteString]
header HeaderName
"Accept-Language" forall s t a b. ASetter s t a b -> b -> s -> t
.~ [ByteString
"en-US,en;q=0.9"]

authOpts :: Text -> Network.Wreq.Options
authOpts :: Text -> Options
authOpts Text
tok = 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
<> Text -> ByteString
TE.encodeUtf8 Text
tok]
               forall a b. a -> (a -> b) -> b
& HeaderName -> Lens' Options [ByteString]
header HeaderName
"Accept" forall s t a b. ASetter s t a b -> b -> s -> t
.~ [ByteString
"application/vnd.gopro.jk.media+json; version=2.0.0"]
               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"]

jsonOpts :: Data.Aeson.Options
jsonOpts :: Options
jsonOpts = Options
defaultOptions {
  fieldLabelModifier :: String -> String
fieldLabelModifier = forall a. (a -> Bool) -> [a] -> [a]
dropWhile (forall a. Eq a => a -> a -> Bool
== Char
'_')
  }

-- | Proxy a request to GoPro with authentication.
proxy :: MonadIO m => Text -> String -> m BL.ByteString
proxy :: forall (m :: * -> *). MonadIO m => Text -> String -> m ByteString
proxy Text
tok String
u = do
  Response ByteString
r <- forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ Options -> String -> IO (Response ByteString)
getWith (Text -> Options
authOpts Text
tok) String
u
  forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ Response ByteString
r forall s a. s -> Getting a s a -> a
^. forall body0 body1.
Lens (Response body0) (Response body1) body0 body1
responseBody

jget :: (MonadIO m, FromJSON a) => Text -> String -> m a
jget :: forall (m :: * -> *) a.
(MonadIO m, FromJSON a) =>
Text -> String -> m a
jget Text
tok = forall (m :: * -> *) a.
(MonadIO m, FromJSON a) =>
Options -> String -> m a
jgetWith (Text -> Options
authOpts Text
tok)

jgetWith :: (MonadIO m, FromJSON a) => Network.Wreq.Options -> String -> m a
jgetWith :: forall (m :: * -> *) a.
(MonadIO m, FromJSON a) =>
Options -> String -> m a
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 (Options -> String -> IO (Response ByteString)
getWith Options
opts String
u 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)

jpostWith :: (MonadIO m, Postable a, FromJSON r) => Network.Wreq.Options -> String -> a -> m r
jpostWith :: forall (m :: * -> *) a r.
(MonadIO m, Postable a, FromJSON r) =>
Options -> String -> a -> m r
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)