System.Directory

module System.Directory(module Directory,module System.Directory) where
import Directory
import Monad(when,filterM)
import IO(isAlreadyExistsError)
import List(nub)
import System.FilePath(takeDirectory,(</>))
import System.Environment(getEnv,lookupEnv)

createDirectoryIfMissing :: Bool -> FilePath -> IO ()
createDirectoryIfMissing parents path =
  do when parents $ createParents path
     createDirectory path `catch` \ e -> if isAlreadyExistsError e
                                         then return ()
                                         else ioError e

  where
     createParents path =
         if parent `elem` ["/",".",path]
         then return ()
         else createDirectoryIfMissing True parent
       where
         parent = takeDirectory path

getHomeDirectory :: IO FilePath
getHomeDirectory = getEnv "HOME"

getAppUserDataDirectory appName = (</>'.':appName) <$> getHomeDirectory

data XdgDirectory = XdgData | XdgConfig | XdgCache
     deriving (Bounded,Eq,Ord,Enum,Read,Show)

getXdgDirectory dir path = (++(subdir</>path)) <$> getHomeDirectory
  where
    subdir = case dir of
               XdgData -> "/.local/share"
               XdgConfig -> "/.config"
               XdgCache -> "/.cache"

    p1</>"" = p1
    p1</>p2 = p1++"/"++p2

getTemporaryDirectory = maybe "/tmp" id <$> lookupEnv "TMPDIR"

removeDirectoryRecursive dirpath =
  do mapM remove =<< listDirectory dirpath
     removeDirectory dirpath
  where
    remove childpath =
      do let path = dirpath++"/"++childpath
         dir <- doesDirectoryExist path
         if dir then removeDirectoryRecursive path
                else removeFile path

listDirectory path =
  filter (`notElem` [".",".."]) <$> getDirectoryContents path

findFile dirs name = findM doesFileExist (nub [dir</>name | dir<-dirs])

-- | Monadic version of List.find
findM p [] = return Nothing
findM p (x:xs) = do yes <- p x
                    if yes then return (Just x) else findM p xs

findFiles dirs name = filterM doesFileExist (nub [dir</>name | dir<-dirs])