-- | Blockfrost authentication scheme instance for HasClient

{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}

module Blockfrost.Client.Auth
  ( Project
  ) where

import Blockfrost.Auth
import Data.CaseInsensitive (mk)
import Data.Proxy (Proxy (..))
import Data.Sequence ((<|))
import GHC.TypeLits
import Servant.API ((:>))
import Servant.Client.Core (Client, HasClient (..), requestHeaders)

import qualified Data.ByteString.Char8
import qualified Data.Text.Encoding

instance {-# OVERLAPS #-} (HasClient m api, KnownSymbol sym) => HasClient m (ProjectAuth '[APIKeyInHeader sym] a :> api) where
  type Client m (ProjectAuth '[APIKeyInHeader sym] a :> api) = Project -> Client m api

  clientWithRoute :: Proxy m
-> Proxy (ProjectAuth '[APIKeyInHeader sym] a :> api)
-> Request
-> Client m (ProjectAuth '[APIKeyInHeader sym] a :> api)
clientWithRoute Proxy m
m Proxy (ProjectAuth '[APIKeyInHeader sym] a :> api)
_ Request
req Project
proj
    = Proxy m -> Proxy api -> Request -> Client m api
forall (m :: * -> *) api.
HasClient m api =>
Proxy m -> Proxy api -> Request -> Client m api
clientWithRoute Proxy m
m (Proxy api
forall k (t :: k). Proxy t
Proxy :: Proxy api)
    (Request -> Client m api) -> Request -> Client m api
forall a b. (a -> b) -> a -> b
$ Request
req { requestHeaders :: Seq Header
requestHeaders = (CI ByteString
headerName, ByteString
headerVal) Header -> Seq Header -> Seq Header
forall a. a -> Seq a -> Seq a
<| Request -> Seq Header
forall body path. RequestF body path -> Seq Header
requestHeaders Request
req  }
      where
        headerVal :: ByteString
headerVal = Text -> ByteString
Data.Text.Encoding.encodeUtf8 (Text -> ByteString) -> Text -> ByteString
forall a b. (a -> b) -> a -> b
$ Project -> Text
projectId Project
proj
        headerName :: CI ByteString
headerName = ByteString -> CI ByteString
forall s. FoldCase s => s -> CI s
mk (ByteString -> CI ByteString) -> ByteString -> CI ByteString
forall a b. (a -> b) -> a -> b
$ String -> ByteString
Data.ByteString.Char8.pack (String -> ByteString) -> String -> ByteString
forall a b. (a -> b) -> a -> b
$ Proxy sym -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (Proxy sym
forall k (t :: k). Proxy t
Proxy @sym)

  hoistClientMonad :: Proxy m
-> Proxy (ProjectAuth '[APIKeyInHeader sym] a :> api)
-> (forall x. mon x -> mon' x)
-> Client mon (ProjectAuth '[APIKeyInHeader sym] a :> api)
-> Client mon' (ProjectAuth '[APIKeyInHeader sym] a :> api)
hoistClientMonad Proxy m
pm Proxy (ProjectAuth '[APIKeyInHeader sym] a :> api)
_ forall x. mon x -> mon' x
nt Client mon (ProjectAuth '[APIKeyInHeader sym] a :> api)
cl = Proxy m
-> Proxy api
-> (forall x. mon x -> mon' x)
-> Client mon api
-> Client mon' api
forall (m :: * -> *) api (mon :: * -> *) (mon' :: * -> *).
HasClient m api =>
Proxy m
-> Proxy api
-> (forall x. mon x -> mon' x)
-> Client mon api
-> Client mon' api
hoistClientMonad Proxy m
pm (Proxy api
forall k (t :: k). Proxy t
Proxy :: Proxy api) forall x. mon x -> mon' x
nt (Client mon api -> Client mon' api)
-> (Project -> Client mon api) -> Project -> Client mon' api
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Client mon (ProjectAuth '[APIKeyInHeader sym] a :> api)
Project -> Client mon api
cl