{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE NoMonomorphismRestriction #-}

module Hack.Utils where

import Hack
import Hack.Constants

import MPSUTF8
import Prelude hiding ((.), (^), (>), lookup, (+), (/))

import Network.CGI hiding (Html)
import Network.URI hiding (path)
import Data.Default

import Control.Arrow ((>>>), (<<<))
import Data.Map (toList, lookup)
import Data.Time
import Text.Template
import qualified Data.ByteString.Lazy.Char8 as B
import Control.Monad (mplus)
import Data.Maybe
import System.IO
import System.Posix.Files
import System.Locale
import System.Directory
import Data.Time.Clock.POSIX
import System.FilePath ((</>))
import Network.URI (unEscapeString)
import Data.Char (ord)

-- import Date.Time

(>) = (>>>)
infixl 8 >

(+) = mplus
infixl 8 +

(/) :: FilePath -> FilePath -> FilePath
(/) = (</>)
infixl 5 /

empty_app :: Application
empty_app = return def

-- usage: app.use [content_type, cache]
use :: [MiddleWare] -> MiddleWare
use = reduce (<<<)

bytesize :: String -> Int
bytesize = B.pack > B.length > from_i

dummy_middleware :: MiddleWare
dummy_middleware = id

dummy_app :: Application
dummy_app _ = return $ def { status = 500 }

escape_html = concatMap fixChar
    where
      fixChar '<' = "<"
      fixChar '>' = ">"
      fixChar '&' = "&"
      fixChar '"' = "\""
      fixChar c | ord c < 0x80 = [c]
      fixChar c = "&#" ++ show (ord c) ++ ";"




show_status_code x = status_code.lookup x
      
      
-- MPS candidate

now :: IO UTCTime
now = getCurrentTime

format_time :: String -> UTCTime -> String
format_time = formatTime defaultTimeLocale

interpolate :: String -> [(String, String)] -> String
interpolate s params = B.unpack $ substitute (B.pack s) (context params)
  where 
    context = map packPair > to_h
    packPair (x, y) = (B.pack x, B.pack y)
    
just_lookup s xs = xs.lookup s .fromJust

httpdate :: UTCTime -> String
httpdate x = x.format_time rfc822DateFormat where

file_size :: String -> IO Integer
file_size path = withFile (path.u2b) ReadMode hFileSize

file_mtime :: String -> IO UTCTime
file_mtime path = getFileStatus (path.u2b) 
                  ^ modificationTime ^ realToFrac ^ posixSecondsToUTCTime

read_binary_file :: String -> IO String
read_binary_file path = path.u2b.B.readFile ^ B.unpack

get_permissions :: String -> IO Permissions
get_permissions path = getPermissions (path.u2b) 

url2unicode :: String -> String
url2unicode s = s.unEscapeString.b2u

get_current_directory :: IO String
get_current_directory = getCurrentDirectory ^ b2u