module WebServer.Server (runServer
    			, URLParams
				, POSTParams
				, Render
	) where

import Network.Socket hiding (send, sendTo, recv, recvFrom)
import Network.Socket.ByteString
import qualified Data.ByteString.Lazy as B

type HTTPParams = [(String, String)]
type ISFinalView = Bool
type HTTPStatus = Int 
type HTTPContentType = (String, String)
type HTTPResponse = (IO ByteString, HTTPStatus, HTTPParams, ISFinalView)

httpStatusCode :: HTTPStatus -> String
httpStatusCode 100 = "Continue" 
httpStatusCode 101 = "Switching Protocols"
httpStatusCode 102 = "Processing"
httpStatusCode 118 = "Connection timed out"
httpStatusCode 200 = "OK"
httpStatusCode 201 = "Created"
httpStatusCode 202 = "Accepted"
httpStatusCode 203 = "Non-Authoritative Information"
httpStatusCode 204 = "No Content"
httpStatusCode 205 = "Reset Content"
httpStatusCode 206 = "Partial Content"
httpStatusCode 207 = "Multi-Status"
httpStatusCode 210 = "Content Different"
httpStatusCode 226 = "IM Used"
httpStatusCode 300 = "Multiple Choices"
httpStatusCode 301 = "Moved Permanently"
httpStatusCode 302 = "Moved Temporarily"
httpStatusCode 303 = "See Other"
httpStatusCode 304 = "Not Modified"
httpStatusCode 305 = "Use Proxy"
httpStatusCode 307 = "Temporary Redirect"
httpStatusCode 310 = "Too many Redirects"
httpStatusCode 400 = "Bad Request"
httpStatusCode 401 = "Unauthorized"
httpStatusCode 402 = "Payment Required"
httpStatusCode 403 = "Forbidden"
httpStatusCode 404 = "Not Found"
httpStatusCode 405 = "Method Not Allowed"
httpStatusCode 406 = "Not Acceptable"
httpStatusCode 407 = "Proxy Authentication Required"
httpStatusCode 408 = "Request Time-out"
httpStatusCode 409 = "Conflict"
httpStatusCode 410 = "Gone"
httpStatusCode 411 = "Length Required"
httpStatusCode 412 = "Precondition Failed"
httpStatusCode 413 = "Request Entity Too Large"
httpStatusCode 414 = "Request URI Too Long"
httpStatusCode 415 = "Unsupported Media Type"
httpStatusCode 416 = "Requested Range Unsatisfiable"
httpStatusCode 417 = "Expectation failed"
httpStatusCode 418 = "I'm a teapot"
httpStatusCode 422 = "Unprocessable entity"
httpStatusCode 423 = "Locked"
httpStatusCode 424 = "Method failure"
httpStatusCode 425 = "Unordered Collection"
httpStatusCode 426 = "Retry With"
httpStatusCode 449 = "Blocked By Windows Parental Controls"
httpStatusCode 450 = "Unrecoverable Error"
httpStatusCode 499 = "Client has closed connection"
httpStatusCode 500 = "Internal Server Error"
httpStatusCode 501 = "Not Implemented"
httpStatusCode 502 = "Bad Gateway"
httpStatusCode 503 = "Service Unavailable"
httpStatusCode 504 = "Gateway Time-out"
httpStatusCode 505 = "HTTP Version Not Supported"
httpStatusCode 506 = "Variant Also Negociate"
httpStatusCode 507 = "Insufficient Storage"
httpStatusCode 508 = "Loop Detected"
httpStatusCode 509 = "Bandwidth Limit Exceeded"
httpStatusCode 510 = "Not Extended"

renderUnhandeledStatus :: HTTPStatus -> HTTPResponse
renderUnhandeledStatus status = ("<!doctype html><html>" ++
									"<head>" ++
										"<meta charset=\"utf-8\"/>" ++
										"<title>" ++ statusText ++ "</title>" ++
									"</head>" ++
									"<body>" ++ 
										"<h1 style=\"text-align: center;\">" ++ statusText ++ "</h1>" ++
										"<hr />" ++
										"<p style=\"text-align: center;\">Flaskell</p>" ++
									"</body>" ++
								"</html>",
								status,
								[],
								True
								)
	where 
		statusText = (show status) ++ " / " ++  (httpStatusCode status)

parseRequest :: (Socket, Sock.HostName) -> Route -> IO ()
parseRequest (handle, addr) routes = Sock.recv handle 1024 >>= renderReponse routes >>= Sock.send handle >>= close
	where
        close a = Sock.sClose handle

startConn :: Socket -> Route -> IO ()
startConn socket routes = forever $ Sock.accept socket >>= parseRequest routes

runServer :: PortNumber -> Route -> IO ()
runServer port routes = withSocketsDo $ do
	sock <- listenOn $ PortNumber port
	startConn sock routes
