{-# OPTIONS -fffi #-}
module Curl ( copyUrl, Cachable(Cachable, Uncachable, MaxAge) )
where

import IO
import Foreign.C.Types ( CInt )
#ifdef HAVE_CURL
import Foreign.C.String ( withCString, CString )
import Monad ( when )
import System.Environment (getEnv)
import Autoconf (darcs_version)
#endif

data Cachable = Cachable | Uncachable | MaxAge !CInt

copyUrl :: String -> String -> Cachable -> IO ()
#ifdef HAVE_CURL
copyUrl u f cache =
  withCString darcs_version $ \vstr ->
  withCString u $ \ustr ->
  withCString f $ \fstr -> do
  ppwd <- getProxyUserPwd
  withCString ppwd $ \pstr -> do
  err <- get_curl vstr pstr fstr ustr (cachableToInt cache)
  when (err /= 0) $ fail $ "Failed to download URL "++ u ++ " : " ++ curl_e err
      where curl_e 1 = "unsupported protocol"
            curl_e 3 = "malformed URL"
            curl_e 5 = "couldn't resolve proxy"
            curl_e 6 = "couldn't resolve host"
            curl_e 7 = "couldn't connect to host"
            curl_e 22 = "HTTP error (404?)"
            curl_e 23 = "libcurl write error"
            curl_e 46 = "bad password"
            curl_e err = "libcurl error code: "++show err
#else
copyUrl _ _ _ = fail "There is no libcurl!"
#endif

#ifdef HAVE_CURL
cachableToInt :: Cachable -> CInt
cachableToInt Cachable = -1
cachableToInt Uncachable = 0
cachableToInt (MaxAge n) = n

foreign import ccall "hscurl.h get_curl"
  get_curl :: CString -> CString -> CString -> CString -> CInt -> IO CInt

getProxyUserPwd :: IO String
getProxyUserPwd = do
 getEnv "DARCS_PROXYUSERPWD" `catch` (\_ -> return "")
#endif
