{-|
Module      : Network.Wai.RequestSpec.Internal.Env
Description : Request environment handling
Copyright   : Alej Cabrera 2015
License     : BSD-3
Maintainer  : cpp.cabrera@gmail.com
Stability   : experimental
Portability : POSIX
-}
module Network.Wai.RequestSpec.Internal.Env (
  Env(..),
  EnvMap,
  ParamValue(..),
  defaultEnv,
  mkHeaders,
  mkParams,
  toEnv
) where

import Data.ByteString (ByteString)
import Data.CaseInsensitive (CI, original, mk)
import Data.Text (Text)
import Data.Text.Encoding (decodeUtf8)
import Network.HTTP.Types
import Network.Wai (Request, requestHeaders, queryString)
import qualified Data.Map as M

data ParamValue
  = Present Text
  | Empty
  | NotFound
    deriving (Show)

type EnvMap k v = M.Map k v
type Headers = EnvMap (CI Text) Text
type Params  = EnvMap Text ParamValue

data Env = Env { headers :: Headers
               , params  :: Params
               } deriving Show

bt :: ByteString -> Text
bt = decodeUtf8

mkParams :: Query -> Params
mkParams query = go query M.empty
  where go [] acc = acc
        go ((a,Nothing):qs) acc = go qs (M.insert (bt a) Empty acc)
        go ((a,Just b):qs) acc  = go qs (M.insert (bt a) (Present . bt $ b) acc)

defaultEnv :: Env
defaultEnv = Env M.empty M.empty

mkHeaders :: RequestHeaders -> Headers
mkHeaders = M.fromList . fmap (\(a,b) -> (mk . bt . original $ a, bt b))

toEnv :: Request -> Env
toEnv r = Env headers' params'
  where headers' = (mkHeaders . requestHeaders) r
        params'  = (mkParams . queryString) r