{-# LANGUAGE CPP #-}
-- File created: 2008-02-03 13:45:20

module Coadjute.Util.File(
   doesPathExist, allPathsExist,
   toAbsolutePath
) where

import System.Directory (getCurrentDirectory)
import System.FilePath  ((</>), isAbsolute)

#if mingw32_HOST_OS
import System.Win32.Types (withTString)
import System.Win32.File  (c_GetFileAttributes)
#else
import Foreign.C.String      (withCString)
import Foreign.Marshal.Alloc (allocaBytes)
import System.FilePath
   (isDrive, dropTrailingPathSeparator, addTrailingPathSeparator)
import System.Posix.Internals (sizeof_stat, lstat)
#endif

import Coadjute.Util.Monad (allM)

-- A significant optimization over using System.Directory functions.
doesPathExist :: FilePath -> IO Bool
#if mingw32_HOST_OS
doesPathExist = flip withTString (fmap (/= 0xffffffff).c_GetFileAttributes)
#else
doesPathExist s =
   allocaBytes sizeof_stat $ \p ->
      withCString
         (if isDrive s
             then addTrailingPathSeparator s
             else dropTrailingPathSeparator s)
         $ \c -> fmap (==0) (lstat c p)
#endif

allPathsExist :: [FilePath] -> IO Bool
allPathsExist = allM doesPathExist

toAbsolutePath :: FilePath -> IO FilePath
toAbsolutePath p =
   if isAbsolute p
      then return p
      else fmap (</> p) getCurrentDirectory