{-# LANGUAGE OverloadedStrings #-}

module Airtable.Query
    ( module Airtable.Table
      -- * Configuration for Airtable requests.
    , AirtableOptions(..)
      -- * Main API
    , getTable
    ) where


import           Airtable.Table

import           Network.Wreq

import           Control.Lens ((^.), (.~), (&))

import           Data.Aeson (FromJSON, ToJSON, eitherDecode)
import           Data.Monoid
import qualified Data.ByteString.Char8 as BC

-- | Options
data AirtableOptions = AirtableOptions {
  -- | the API key for your project
    apiKey :: String
  -- | the app ID for your project (http://api.airtable.com/v0/...)
  , appId :: String  
  -- | api version (http://api.airtable.com/v../...)
  , apiVersion :: Int
  }

-- | Airtable options defaulting to API version 0. Please change the 
--   'apiKey' and 'appId' fields.
defaultOptions :: AirtableOptions 
defaultOptions = AirtableOptions {
    apiKey = ""
  , appId = ""
  , apiVersion = 0
  }

-- | Base airtable API string. 
base_url :: String
base_url = "https://api.airtable.com/"

-- | Retrieve a table from airtable.com given its name. 
getTable :: (FromJSON a) => AirtableOptions -> TableName -> IO (Table a)
getTable opts tname = getTableFromUrl net_otps url 
  where
    net_otps = defaults & header "Authorization" .~ ["Bearer " <> BC.pack (apiKey opts)] 
    url  =   base_url 
          <> "v" 
          <> show (apiVersion opts) 
          <> "/" 
          <> appId opts 
          <> "/" 
          <> tname

getTableFromUrl :: (FromJSON a) => Options -> String -> IO (Table a)
getTableFromUrl opts url = do
  resp <- getWith opts url
  getMore (fromResp resp)
  where
    getMore tbl = case tableOffset tbl of 
      Just offset -> do
        resp <- getWith (opts & param "offset" .~ [offset]) url
        getMore $ fromResp resp <> tbl
      Nothing -> 
        pure tbl

    fromResp r = decoder $ r ^. responseBody
      where
        decoder b = case eitherDecode b of 
          Left e -> error $ e <> "\nSource string: " <> show b
          Right r -> r