{-# LANGUAGE TypeSynonymInstances #-}

module Hack where

import Data.Default

data RequestMethod =
     OPTIONS
  |  GET
  |  HEAD
  |  POST
  |  PUT
  |  DELETE
  |  TRACE
  |  CONNECT
  deriving (Show, Read, Eq)

data Hack_UrlScheme = HTTP | HTTPS deriving (Show, Eq)

type Map = [(String, String)]

-- newtype HackErrors = HackErrors { unHackErrors :: String -> IO () }

type Stream = String -> IO ()
type HackErrors = Stream

instance Show HackErrors where
  show _ = "HackHackErrors"

data Env = Env 
  {  request_method :: RequestMethod
  ,  script_name :: String
  ,  path_info :: String
  ,  query_string :: String
  ,  server_name :: String
  ,  server_port :: Int
  ,  http :: Map
  ,  hack_version :: [Int]
  ,  hack_url_scheme :: Hack_UrlScheme
  ,  hack_input :: String
  ,  hack_errors :: HackErrors
  ,  hack_multithread :: Bool
  ,  hack_multiprocess :: Bool
  ,  hack_run_once :: Bool
  ,  custom :: Map
  }
  deriving (Show)

data Response = Response 
  {  status :: Int
  ,  headers :: Map
  ,  body :: String
  }
  deriving (Show)

instance Default RequestMethod where
  def = GET

instance Default Hack_UrlScheme where
  def = HTTP

instance Default Response where
  def = Response def def def

instance Default Env where
  def = Env def def def def def def def def def def const_io False False False def
    where const_io = const (return ())

type Application = Env -> IO Response

type Middleware = Application -> Application

-- compatibility
type MiddleWare = Middleware