{-# LANGUAGE DataKinds            #-}

{-# LANGUAGE FlexibleContexts     #-}

{-# LANGUAGE FlexibleInstances    #-}

{-# LANGUAGE KindSignatures       #-}

{-# LANGUAGE OverloadedLabels     #-}

{-# LANGUAGE OverloadedStrings    #-}

{-# LANGUAGE TypeFamilies         #-}

{-# LANGUAGE TypeOperators        #-}

{-# LANGUAGE TypeSynonymInstances #-}



module Rakuten.Client (

      AppId

    , RakutenClient

    , defaultRaktenClient

    , Client(..)

    ) where



import           Control.Lens       hiding ((:>))

import           Data.Default.Class (Default (def))

import           Data.Extensible

import           Data.Function      ((&))

import           Data.Text          (Text)

import           Network.HTTP.Req   (Option, Scheme (Https), Url, https, (/:),

                                     (=:))

import           Rakuten.Types



-- |

-- Application ID

type AppId = Text



type RakutenClient =

  Record '[

    "applicationId" ':> Text,

    "affiliateId" ':> Maybe Text,

    "callback" ':> Maybe Text,

    "elements" ':> [Text]

  ]



defaultRaktenClient :: AppId -> RakutenClient

defaultRaktenClient appId = def & #applicationId .~ appId



-- |

-- By using type class, the same functions can be used for mock servers and local hosts.

class Client a where

  type ClientScheme a :: Scheme

  baseUrl :: a -> Url (ClientScheme a)

  mkHeader :: a -> Option scheme



instance Client RakutenClient where

  type ClientScheme RakutenClient = 'Https

  baseUrl = const (https "app.rakuten.co.jp" /: "services" /: "api")

  mkHeader = mappend ("format" =: ("json" :: Text)) . toParams