{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE TypeFamilies #-}

module Network.OAuth2.Provider.Fitbit where

import Control.Monad (mzero)
import Data.Aeson
import Data.Map.Strict qualified as Map
import Data.Set qualified as Set
import Data.Text.Lazy (Text)
import Network.OAuth.OAuth2
import Network.OAuth2.Experiment
import URI.ByteString.QQ

data Fitbit = Fitbit deriving (Fitbit -> Fitbit -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Fitbit -> Fitbit -> Bool
$c/= :: Fitbit -> Fitbit -> Bool
== :: Fitbit -> Fitbit -> Bool
$c== :: Fitbit -> Fitbit -> Bool
Eq, Int -> Fitbit -> ShowS
[Fitbit] -> ShowS
Fitbit -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Fitbit] -> ShowS
$cshowList :: [Fitbit] -> ShowS
show :: Fitbit -> String
$cshow :: Fitbit -> String
showsPrec :: Int -> Fitbit -> ShowS
$cshowsPrec :: Int -> Fitbit -> ShowS
Show)

type instance IdpUserInfo Fitbit = FitbitUser

defaultFitbitApp :: IdpApplication 'AuthorizationCode Fitbit
defaultFitbitApp :: IdpApplication 'AuthorizationCode Fitbit
defaultFitbitApp =
  AuthorizationCodeIdpApplication
    { $sel:idpAppClientId:AuthorizationCodeIdpApplication :: ClientId
idpAppClientId = ClientId
""
    , $sel:idpAppClientSecret:AuthorizationCodeIdpApplication :: ClientSecret
idpAppClientSecret = ClientSecret
""
    , $sel:idpAppScope:AuthorizationCodeIdpApplication :: Set Scope
idpAppScope = forall a. Set a
Set.empty
    , $sel:idpAppAuthorizeExtraParams:AuthorizationCodeIdpApplication :: Map Text Text
idpAppAuthorizeExtraParams = forall k a. Map k a
Map.empty
    , $sel:idpAppAuthorizeState:AuthorizationCodeIdpApplication :: AuthorizeState
idpAppAuthorizeState = AuthorizeState
"CHANGE_ME"
    , $sel:idpAppRedirectUri:AuthorizationCodeIdpApplication :: URI
idpAppRedirectUri = [uri|http://localhost|]
    , $sel:idpAppName:AuthorizationCodeIdpApplication :: Text
idpAppName = Text
"default-fitbit-App"
    , $sel:idpAppTokenRequestAuthenticationMethod:AuthorizationCodeIdpApplication :: ClientAuthenticationMethod
idpAppTokenRequestAuthenticationMethod = ClientAuthenticationMethod
ClientSecretBasic
    , $sel:idp:AuthorizationCodeIdpApplication :: Idp Fitbit
idp = Idp Fitbit
defaultFitbitIdp
    }

defaultFitbitIdp :: Idp Fitbit
defaultFitbitIdp :: Idp Fitbit
defaultFitbitIdp =
  Idp
    { $sel:idpFetchUserInfo:Idp :: forall (m :: * -> *).
(FromJSON (IdpUserInfo Fitbit), MonadIO m) =>
Manager
-> AccessToken -> URI -> ExceptT ByteString m (IdpUserInfo Fitbit)
idpFetchUserInfo = forall a (m :: * -> *).
(FromJSON a, MonadIO m) =>
Manager -> AccessToken -> URI -> ExceptT ByteString m a
authGetJSON @(IdpUserInfo Fitbit)
    , $sel:idpUserInfoEndpoint:Idp :: URI
idpUserInfoEndpoint = [uri|https://api.fitbit.com/1/user/-/profile.json|]
    , $sel:idpAuthorizeEndpoint:Idp :: URI
idpAuthorizeEndpoint = [uri|https://www.fitbit.com/oauth2/authorize|]
    , $sel:idpTokenEndpoint:Idp :: URI
idpTokenEndpoint = [uri|https://api.fitbit.com/oauth2/token|]
    }

data FitbitUser = FitbitUser
  { FitbitUser -> Text
userId :: Text
  , FitbitUser -> Text
userName :: Text
  , FitbitUser -> Int
userAge :: Int
  }
  deriving (Int -> FitbitUser -> ShowS
[FitbitUser] -> ShowS
FitbitUser -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [FitbitUser] -> ShowS
$cshowList :: [FitbitUser] -> ShowS
show :: FitbitUser -> String
$cshow :: FitbitUser -> String
showsPrec :: Int -> FitbitUser -> ShowS
$cshowsPrec :: Int -> FitbitUser -> ShowS
Show, FitbitUser -> FitbitUser -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: FitbitUser -> FitbitUser -> Bool
$c/= :: FitbitUser -> FitbitUser -> Bool
== :: FitbitUser -> FitbitUser -> Bool
$c== :: FitbitUser -> FitbitUser -> Bool
Eq)

instance FromJSON FitbitUser where
  parseJSON :: Value -> Parser FitbitUser
parseJSON (Object Object
o) =
    Text -> Text -> Int -> FitbitUser
FitbitUser
      forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ((Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"user") forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"encodedId"))
      forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ((Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"user") forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"fullName"))
      forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ((Object
o forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"user") forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (forall a. FromJSON a => Object -> Key -> Parser a
.: Key
"age"))
  parseJSON Value
_ = forall (m :: * -> *) a. MonadPlus m => m a
mzero