module Chu2.Interface.Hack2 where

import Data.ByteString (ByteString)
import qualified Hack2 as Hack2
import Data.ByteString.Char8 (pack)

import Chu2.FFI

chu2RequestMethodFromHack2RequestMethod :: Hack2.RequestMethod -> RequestMethod
chu2RequestMethodFromHack2RequestMethod Hack2.OPTIONS = OPTIONS
chu2RequestMethodFromHack2RequestMethod Hack2.GET     = GET
chu2RequestMethodFromHack2RequestMethod Hack2.HEAD    = HEAD
chu2RequestMethodFromHack2RequestMethod Hack2.POST    = POST
chu2RequestMethodFromHack2RequestMethod Hack2.PUT     = PUT
chu2RequestMethodFromHack2RequestMethod Hack2.DELETE  = DELETE
chu2RequestMethodFromHack2RequestMethod Hack2.TRACE   = TRACE
chu2RequestMethodFromHack2RequestMethod Hack2.CONNECT = CONNECT


chu2UrlSchemeFromHack2UrlScheme :: Hack2.HackUrlScheme -> Chu2UrlScheme
chu2UrlSchemeFromHack2UrlScheme Hack2.HTTP = HTTP
chu2UrlSchemeFromHack2UrlScheme Hack2.HTTPS = HTTPS

chu2ErrorsFromHack2Errors :: Hack2.HackErrors -> Chu2Errors
chu2ErrorsFromHack2Errors = Hack2.unHackErrors

chu2EnvFromHack2Env :: Hack2.Env -> Env
chu2EnvFromHack2Env e = 
  Env
    {
      requestMethod  = chu2RequestMethodFromHack2RequestMethod $ Hack2.requestMethod  e
    , scriptName     = Hack2.scriptName     e
    , pathInfo       = Hack2.pathInfo       e
    , queryString    = Hack2.queryString    e
    , serverName     = Hack2.serverName     e
    , serverPort     = pack $ show $ Hack2.serverPort     e
    , httpHeaders    = Hack2.httpHeaders    e
    , chu2Version    = pack $ show $ Hack2.hackVersion    e
    , chu2UrlScheme  = chu2UrlSchemeFromHack2UrlScheme $ Hack2.hackUrlScheme  e
    , chu2Input      = Hack2.hackInput      e
    , chu2Errors     = chu2ErrorsFromHack2Errors $ Hack2.hackErrors     e
    , chu2Headers    = Hack2.hackHeaders    e
    }
    

chu2ResponseToHack2Response :: Response -> Hack2.Response
chu2ResponseToHack2Response r =
  Hack2.Response
    {
      Hack2.status   = showStatus $ status   r
    , Hack2.headers  = headers  r
    , Hack2.body     = body     r
    }

showStatus :: Status -> Int
showStatus OK = 200
showStatus Created = 201
showStatus Accepted = 202
showStatus NoContent = 204
showStatus MultipleChoices = 300
showStatus MovedPermanently = 301
showStatus SeeOther = 303
showStatus NotModified = 304
showStatus MovedTemporarily = 307
showStatus BadRequest = 400
showStatus Unauthorized = 401
showStatus Forbidden = 403
showStatus NotFound = 404
showStatus MethodNotAllowed = 405
showStatus NotAcceptable = 406
showStatus Conflict = 409
showStatus Gone = 410
showStatus PreconditionFailed = 412
showStatus RequestEntityTooLarge = 413
showStatus RequestURItooLong = 414
showStatus UnsupportedMediaType = 415
showStatus NotImplemented = 501
showStatus ServiceUnavailable = 503


type Application = Env -> IO Response

chu2ApplicationToHack2Application :: Application -> Hack2.Application
chu2ApplicationToHack2Application app = \hack2Env -> do
  chu2Response <- app (chu2EnvFromHack2Env hack2Env)
  return (chu2ResponseToHack2Response chu2Response)