module Network.Livy.Request
  ( 
    get
  , getQuery
  , post
  , postBody
  , postJSON
  , delete
    
  , setHost
  , setPort
  ) where
import           Control.Lens ((&))
import           Data.Aeson
import qualified Data.ByteString as S
import qualified Data.HashMap.Strict as Map
import           Data.Text (Text)
import qualified Data.Text as T
import           Network.HTTP.Client
import           Network.HTTP.Types
import           Network.Livy.Types
get :: ToPath a => a -> Request
get x = defaultRequest { path = toPath x }
getQuery :: (ToPath a, ToQuery a) => a -> Request
getQuery x = get x & setQueryString (toQueryString x)
post :: ToPath a => a -> Request
post x = (get x) { method = "POST" }
postBody
  :: ToPath a
  =>  a 
  -> [(Text, Text)] 
  -> Request
postBody x kv = (post x)
  { requestHeaders = [(hContentType, "application/json")]
  , requestBody    = formatRequestBody kv
  }
postJSON :: (ToPath a, ToJSON a) => a -> Request
postJSON x = (post x)
  { requestHeaders = [(hContentType, "application/json")]
  , requestBody    = RequestBodyLBS $ encode x
  }
delete :: ToPath a => a -> Request
delete x = (get x) { method = "DELETE" }
setHost :: S.ByteString -> Request -> Request
setHost h req = req { host = h }
setPort :: Int -> Request -> Request
setPort p req = req { port = p }
formatRequestBody :: [(Text, Text)] -> RequestBody
formatRequestBody = RequestBodyLBS . encode . Map.fromList . filter (not . T.null . snd)