{-# LANGUAGE OverloadedStrings #-}

import Control.Monad.IO.Class (liftIO)
import Control.Monad.Trans.Either (runEitherT)
import Servant.Crud (API, DeleteFile, GetFile, PutFile)
import Servant.Client (BaseUrl(..), Client, Scheme(..), client)
import Servant (Proxy(..), (:<|>)(..))
import Turtle (argInt, options)

import qualified Data.Text.IO as Text

-- | Example use of autogenerated `API` bindings
main :: IO ()
main = do
    port <- options "CRUD client" (argInt "port" "The port to connect to")

    -- Note that you can use `servant` to bind to any web API, not just APIs
    -- hosted by a `servant` server.  For example, here is some code using
    -- `servant` to create bindings to the Google Translate API:
    --
    -- https://github.com/dmjio/google-translate/blob/master/src/Web/Google/Translate.hs

    let -- | Autogenerated API binding for the `PutFile` endpoint
        putFile    :: Client PutFile

        -- | Autogenerated API binding for the `GetFile` endpoint
        getFile    :: Client GetFile

        -- | Autogenerated API binding for the `DeleteFile` endpoint
        deleteFile :: Client DeleteFile

        (putFile :<|> getFile :<|> deleteFile) =
            client (Proxy :: Proxy API) (BaseUrl Http "localhost" port)

    e <- runEitherT (do
        -- This issues a `PUT` request against the `/foo.txt` endpoint with
        -- a request body of `"Hello, world!"` encoded as JSON
        --
        -- Our server will interpret this as a command to create a file named
        -- `foo.txt` with the contents `"Hello, world!"`
        putFile "foo.txt" "Hello, world!"

        -- This issues a `GET` request against the `/foo.txt` endpoint
        --
        -- Our server will interpret this as a command to fetch the contents of
        -- the file named `foo.txt` and return a response body containing
        -- `"Hello, world!"` encoded as JSON
        txt <- getFile "foo.txt"
        liftIO (Text.putStrLn txt)

        -- This issues a `DELETE` request against the `/foo.txt` endpoint
        --
        -- Our server will interpret this as a command to delete the file named
        -- `foo.txt`
        deleteFile "foo.txt" )
    case e of
        Left err -> print err
        Right r  -> return r
