module Spotify.Types.Auth where

import Spotify.Types.Internal.CustomJSON

import Control.Monad ((>=>))
import Data.Aeson (FromJSON, parseJSON)
import Data.ByteString.Base64 qualified as B64
import Data.String (IsString)
import Data.Text (Text)
import Data.Text.Encoding (decodeUtf8, encodeUtf8)
import GHC.Generics (Generic)
import Servant.API (FromHttpApiData, ToHttpApiData (toUrlPiece))

newtype ClientId = ClientId {ClientId -> Text
unwrap :: Text}
    deriving newtype (ClientId -> ClientId -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ClientId -> ClientId -> Bool
$c/= :: ClientId -> ClientId -> Bool
== :: ClientId -> ClientId -> Bool
$c== :: ClientId -> ClientId -> Bool
Eq, Eq ClientId
ClientId -> ClientId -> Bool
ClientId -> ClientId -> Ordering
ClientId -> ClientId -> ClientId
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: ClientId -> ClientId -> ClientId
$cmin :: ClientId -> ClientId -> ClientId
max :: ClientId -> ClientId -> ClientId
$cmax :: ClientId -> ClientId -> ClientId
>= :: ClientId -> ClientId -> Bool
$c>= :: ClientId -> ClientId -> Bool
> :: ClientId -> ClientId -> Bool
$c> :: ClientId -> ClientId -> Bool
<= :: ClientId -> ClientId -> Bool
$c<= :: ClientId -> ClientId -> Bool
< :: ClientId -> ClientId -> Bool
$c< :: ClientId -> ClientId -> Bool
compare :: ClientId -> ClientId -> Ordering
$ccompare :: ClientId -> ClientId -> Ordering
Ord, Int -> ClientId -> ShowS
[ClientId] -> ShowS
ClientId -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ClientId] -> ShowS
$cshowList :: [ClientId] -> ShowS
show :: ClientId -> String
$cshow :: ClientId -> String
showsPrec :: Int -> ClientId -> ShowS
$cshowsPrec :: Int -> ClientId -> ShowS
Show, String -> ClientId
forall a. (String -> a) -> IsString a
fromString :: String -> ClientId
$cfromString :: String -> ClientId
IsString, ClientId -> Builder
ClientId -> ByteString
ClientId -> Text
forall a.
(a -> Text)
-> (a -> Builder)
-> (a -> ByteString)
-> (a -> Text)
-> (a -> Builder)
-> ToHttpApiData a
toEncodedQueryParam :: ClientId -> Builder
$ctoEncodedQueryParam :: ClientId -> Builder
toQueryParam :: ClientId -> Text
$ctoQueryParam :: ClientId -> Text
toHeader :: ClientId -> ByteString
$ctoHeader :: ClientId -> ByteString
toEncodedUrlPiece :: ClientId -> Builder
$ctoEncodedUrlPiece :: ClientId -> Builder
toUrlPiece :: ClientId -> Text
$ctoUrlPiece :: ClientId -> Text
ToHttpApiData)

newtype ClientSecret = ClientSecret {ClientSecret -> Text
unwrap :: Text}
    deriving newtype (ClientSecret -> ClientSecret -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ClientSecret -> ClientSecret -> Bool
$c/= :: ClientSecret -> ClientSecret -> Bool
== :: ClientSecret -> ClientSecret -> Bool
$c== :: ClientSecret -> ClientSecret -> Bool
Eq, Eq ClientSecret
ClientSecret -> ClientSecret -> Bool
ClientSecret -> ClientSecret -> Ordering
ClientSecret -> ClientSecret -> ClientSecret
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: ClientSecret -> ClientSecret -> ClientSecret
$cmin :: ClientSecret -> ClientSecret -> ClientSecret
max :: ClientSecret -> ClientSecret -> ClientSecret
$cmax :: ClientSecret -> ClientSecret -> ClientSecret
>= :: ClientSecret -> ClientSecret -> Bool
$c>= :: ClientSecret -> ClientSecret -> Bool
> :: ClientSecret -> ClientSecret -> Bool
$c> :: ClientSecret -> ClientSecret -> Bool
<= :: ClientSecret -> ClientSecret -> Bool
$c<= :: ClientSecret -> ClientSecret -> Bool
< :: ClientSecret -> ClientSecret -> Bool
$c< :: ClientSecret -> ClientSecret -> Bool
compare :: ClientSecret -> ClientSecret -> Ordering
$ccompare :: ClientSecret -> ClientSecret -> Ordering
Ord, Int -> ClientSecret -> ShowS
[ClientSecret] -> ShowS
ClientSecret -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ClientSecret] -> ShowS
$cshowList :: [ClientSecret] -> ShowS
show :: ClientSecret -> String
$cshow :: ClientSecret -> String
showsPrec :: Int -> ClientSecret -> ShowS
$cshowsPrec :: Int -> ClientSecret -> ShowS
Show, String -> ClientSecret
forall a. (String -> a) -> IsString a
fromString :: String -> ClientSecret
$cfromString :: String -> ClientSecret
IsString)

newtype AccessToken = AccessToken {AccessToken -> Text
unwrap :: Text}
    deriving newtype (AccessToken -> AccessToken -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: AccessToken -> AccessToken -> Bool
$c/= :: AccessToken -> AccessToken -> Bool
== :: AccessToken -> AccessToken -> Bool
$c== :: AccessToken -> AccessToken -> Bool
Eq, Eq AccessToken
AccessToken -> AccessToken -> Bool
AccessToken -> AccessToken -> Ordering
AccessToken -> AccessToken -> AccessToken
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: AccessToken -> AccessToken -> AccessToken
$cmin :: AccessToken -> AccessToken -> AccessToken
max :: AccessToken -> AccessToken -> AccessToken
$cmax :: AccessToken -> AccessToken -> AccessToken
>= :: AccessToken -> AccessToken -> Bool
$c>= :: AccessToken -> AccessToken -> Bool
> :: AccessToken -> AccessToken -> Bool
$c> :: AccessToken -> AccessToken -> Bool
<= :: AccessToken -> AccessToken -> Bool
$c<= :: AccessToken -> AccessToken -> Bool
< :: AccessToken -> AccessToken -> Bool
$c< :: AccessToken -> AccessToken -> Bool
compare :: AccessToken -> AccessToken -> Ordering
$ccompare :: AccessToken -> AccessToken -> Ordering
Ord, Int -> AccessToken -> ShowS
[AccessToken] -> ShowS
AccessToken -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [AccessToken] -> ShowS
$cshowList :: [AccessToken] -> ShowS
show :: AccessToken -> String
$cshow :: AccessToken -> String
showsPrec :: Int -> AccessToken -> ShowS
$cshowsPrec :: Int -> AccessToken -> ShowS
Show, String -> AccessToken
forall a. (String -> a) -> IsString a
fromString :: String -> AccessToken
$cfromString :: String -> AccessToken
IsString)
    deriving newtype (Value -> Parser [AccessToken]
Value -> Parser AccessToken
forall a.
(Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a
parseJSONList :: Value -> Parser [AccessToken]
$cparseJSONList :: Value -> Parser [AccessToken]
parseJSON :: Value -> Parser AccessToken
$cparseJSON :: Value -> Parser AccessToken
FromJSON)
instance ToHttpApiData AccessToken where
    toUrlPiece :: AccessToken -> Text
toUrlPiece (AccessToken Text
t) = forall a. ToHttpApiData a => a -> Text
toUrlPiece forall a b. (a -> b) -> a -> b
$ Text
"Bearer " forall a. Semigroup a => a -> a -> a
<> Text
t

newtype RefreshToken = RefreshToken {RefreshToken -> Text
unwrap :: Text}
    deriving newtype (RefreshToken -> RefreshToken -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: RefreshToken -> RefreshToken -> Bool
$c/= :: RefreshToken -> RefreshToken -> Bool
== :: RefreshToken -> RefreshToken -> Bool
$c== :: RefreshToken -> RefreshToken -> Bool
Eq, Eq RefreshToken
RefreshToken -> RefreshToken -> Bool
RefreshToken -> RefreshToken -> Ordering
RefreshToken -> RefreshToken -> RefreshToken
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: RefreshToken -> RefreshToken -> RefreshToken
$cmin :: RefreshToken -> RefreshToken -> RefreshToken
max :: RefreshToken -> RefreshToken -> RefreshToken
$cmax :: RefreshToken -> RefreshToken -> RefreshToken
>= :: RefreshToken -> RefreshToken -> Bool
$c>= :: RefreshToken -> RefreshToken -> Bool
> :: RefreshToken -> RefreshToken -> Bool
$c> :: RefreshToken -> RefreshToken -> Bool
<= :: RefreshToken -> RefreshToken -> Bool
$c<= :: RefreshToken -> RefreshToken -> Bool
< :: RefreshToken -> RefreshToken -> Bool
$c< :: RefreshToken -> RefreshToken -> Bool
compare :: RefreshToken -> RefreshToken -> Ordering
$ccompare :: RefreshToken -> RefreshToken -> Ordering
Ord, Int -> RefreshToken -> ShowS
[RefreshToken] -> ShowS
RefreshToken -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [RefreshToken] -> ShowS
$cshowList :: [RefreshToken] -> ShowS
show :: RefreshToken -> String
$cshow :: RefreshToken -> String
showsPrec :: Int -> RefreshToken -> ShowS
$cshowsPrec :: Int -> RefreshToken -> ShowS
Show, String -> RefreshToken
forall a. (String -> a) -> IsString a
fromString :: String -> RefreshToken
$cfromString :: String -> RefreshToken
IsString)
    deriving newtype (Value -> Parser [RefreshToken]
Value -> Parser RefreshToken
forall a.
(Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a
parseJSONList :: Value -> Parser [RefreshToken]
$cparseJSONList :: Value -> Parser [RefreshToken]
parseJSON :: Value -> Parser RefreshToken
$cparseJSON :: Value -> Parser RefreshToken
FromJSON)
newtype AuthCode = AuthCode {AuthCode -> Text
unwrap :: Text}
    deriving newtype (AuthCode -> AuthCode -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: AuthCode -> AuthCode -> Bool
$c/= :: AuthCode -> AuthCode -> Bool
== :: AuthCode -> AuthCode -> Bool
$c== :: AuthCode -> AuthCode -> Bool
Eq, Eq AuthCode
AuthCode -> AuthCode -> Bool
AuthCode -> AuthCode -> Ordering
AuthCode -> AuthCode -> AuthCode
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: AuthCode -> AuthCode -> AuthCode
$cmin :: AuthCode -> AuthCode -> AuthCode
max :: AuthCode -> AuthCode -> AuthCode
$cmax :: AuthCode -> AuthCode -> AuthCode
>= :: AuthCode -> AuthCode -> Bool
$c>= :: AuthCode -> AuthCode -> Bool
> :: AuthCode -> AuthCode -> Bool
$c> :: AuthCode -> AuthCode -> Bool
<= :: AuthCode -> AuthCode -> Bool
$c<= :: AuthCode -> AuthCode -> Bool
< :: AuthCode -> AuthCode -> Bool
$c< :: AuthCode -> AuthCode -> Bool
compare :: AuthCode -> AuthCode -> Ordering
$ccompare :: AuthCode -> AuthCode -> Ordering
Ord, Int -> AuthCode -> ShowS
[AuthCode] -> ShowS
AuthCode -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [AuthCode] -> ShowS
$cshowList :: [AuthCode] -> ShowS
show :: AuthCode -> String
$cshow :: AuthCode -> String
showsPrec :: Int -> AuthCode -> ShowS
$cshowsPrec :: Int -> AuthCode -> ShowS
Show, String -> AuthCode
forall a. (String -> a) -> IsString a
fromString :: String -> AuthCode
$cfromString :: String -> AuthCode
IsString, ByteString -> Either Text AuthCode
Text -> Either Text AuthCode
forall a.
(Text -> Either Text a)
-> (ByteString -> Either Text a)
-> (Text -> Either Text a)
-> FromHttpApiData a
parseQueryParam :: Text -> Either Text AuthCode
$cparseQueryParam :: Text -> Either Text AuthCode
parseHeader :: ByteString -> Either Text AuthCode
$cparseHeader :: ByteString -> Either Text AuthCode
parseUrlPiece :: Text -> Either Text AuthCode
$cparseUrlPiece :: Text -> Either Text AuthCode
FromHttpApiData)
    deriving newtype (Value -> Parser [AuthCode]
Value -> Parser AuthCode
forall a.
(Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a
parseJSONList :: Value -> Parser [AuthCode]
$cparseJSONList :: Value -> Parser [AuthCode]
parseJSON :: Value -> Parser AuthCode
$cparseJSON :: Value -> Parser AuthCode
FromJSON)

data IdAndSecret = IdAndSecret ClientId ClientSecret
instance ToHttpApiData IdAndSecret where
    toUrlPiece :: IdAndSecret -> Text
toUrlPiece (IdAndSecret (ClientId Text
i) (ClientSecret Text
s)) =
        forall a. ToHttpApiData a => a -> Text
toUrlPiece forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text
"Basic " <>) forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Text
decodeUtf8 forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> ByteString
B64.encode forall a b. (a -> b) -> a -> b
$ Text -> ByteString
encodeUtf8 forall a b. (a -> b) -> a -> b
$ Text
i forall a. Semigroup a => a -> a -> a
<> Text
":" forall a. Semigroup a => a -> a -> a
<> Text
s

data TokenType
    = TokenTypeBearer
    deriving (TokenType -> TokenType -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: TokenType -> TokenType -> Bool
$c/= :: TokenType -> TokenType -> Bool
== :: TokenType -> TokenType -> Bool
$c== :: TokenType -> TokenType -> Bool
Eq, Eq TokenType
TokenType -> TokenType -> Bool
TokenType -> TokenType -> Ordering
TokenType -> TokenType -> TokenType
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: TokenType -> TokenType -> TokenType
$cmin :: TokenType -> TokenType -> TokenType
max :: TokenType -> TokenType -> TokenType
$cmax :: TokenType -> TokenType -> TokenType
>= :: TokenType -> TokenType -> Bool
$c>= :: TokenType -> TokenType -> Bool
> :: TokenType -> TokenType -> Bool
$c> :: TokenType -> TokenType -> Bool
<= :: TokenType -> TokenType -> Bool
$c<= :: TokenType -> TokenType -> Bool
< :: TokenType -> TokenType -> Bool
$c< :: TokenType -> TokenType -> Bool
compare :: TokenType -> TokenType -> Ordering
$ccompare :: TokenType -> TokenType -> Ordering
Ord, Int -> TokenType -> ShowS
[TokenType] -> ShowS
TokenType -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [TokenType] -> ShowS
$cshowList :: [TokenType] -> ShowS
show :: TokenType -> String
$cshow :: TokenType -> String
showsPrec :: Int -> TokenType -> ShowS
$cshowsPrec :: Int -> TokenType -> ShowS
Show, forall x. Rep TokenType x -> TokenType
forall x. TokenType -> Rep TokenType x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep TokenType x -> TokenType
$cfrom :: forall x. TokenType -> Rep TokenType x
Generic)
instance FromJSON TokenType where
    parseJSON :: Value -> Parser TokenType
parseJSON =
        forall a. FromJSON a => Value -> Parser a
parseJSON forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> \case
            String
"Bearer" -> forall (f :: * -> *) a. Applicative f => a -> f a
pure TokenType
TokenTypeBearer
            String
s -> forall (m :: * -> *) a. MonadFail m => String -> m a
fail forall a b. (a -> b) -> a -> b
$ String
"unknown type: " forall a. Semigroup a => a -> a -> a
<> String
s

data TokenResponse = TokenResponse
    { TokenResponse -> AccessToken
accessToken :: AccessToken
    , TokenResponse -> TokenType
tokenType :: TokenType
    , TokenResponse -> Int
expiresIn :: Int
    , TokenResponse -> Text
scope :: Text
    }
    deriving (TokenResponse -> TokenResponse -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: TokenResponse -> TokenResponse -> Bool
$c/= :: TokenResponse -> TokenResponse -> Bool
== :: TokenResponse -> TokenResponse -> Bool
$c== :: TokenResponse -> TokenResponse -> Bool
Eq, Eq TokenResponse
TokenResponse -> TokenResponse -> Bool
TokenResponse -> TokenResponse -> Ordering
TokenResponse -> TokenResponse -> TokenResponse
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: TokenResponse -> TokenResponse -> TokenResponse
$cmin :: TokenResponse -> TokenResponse -> TokenResponse
max :: TokenResponse -> TokenResponse -> TokenResponse
$cmax :: TokenResponse -> TokenResponse -> TokenResponse
>= :: TokenResponse -> TokenResponse -> Bool
$c>= :: TokenResponse -> TokenResponse -> Bool
> :: TokenResponse -> TokenResponse -> Bool
$c> :: TokenResponse -> TokenResponse -> Bool
<= :: TokenResponse -> TokenResponse -> Bool
$c<= :: TokenResponse -> TokenResponse -> Bool
< :: TokenResponse -> TokenResponse -> Bool
$c< :: TokenResponse -> TokenResponse -> Bool
compare :: TokenResponse -> TokenResponse -> Ordering
$ccompare :: TokenResponse -> TokenResponse -> Ordering
Ord, Int -> TokenResponse -> ShowS
[TokenResponse] -> ShowS
TokenResponse -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [TokenResponse] -> ShowS
$cshowList :: [TokenResponse] -> ShowS
show :: TokenResponse -> String
$cshow :: TokenResponse -> String
showsPrec :: Int -> TokenResponse -> ShowS
$cshowsPrec :: Int -> TokenResponse -> ShowS
Show, forall x. Rep TokenResponse x -> TokenResponse
forall x. TokenResponse -> Rep TokenResponse x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep TokenResponse x -> TokenResponse
$cfrom :: forall x. TokenResponse -> Rep TokenResponse x
Generic)
    deriving (Value -> Parser [TokenResponse]
Value -> Parser TokenResponse
forall a.
(Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a
parseJSONList :: Value -> Parser [TokenResponse]
$cparseJSONList :: Value -> Parser [TokenResponse]
parseJSON :: Value -> Parser TokenResponse
$cparseJSON :: Value -> Parser TokenResponse
FromJSON) via CustomJSON TokenResponse