    module General.Glob(globFile, globDir) where

    import General.Code

    -- Find the file given directories, extensions, search
    -- supports * glob key
    globFile :: [FilePath] -> [String] -> FilePath -> IO [FilePath]
    globFile dirs exts file = f poss
        where
            f [] = exitMessage $ ["Could not find file:"
                                 , "    " ++ file
                                 ,"Searched:"] ++
                                 map ("    " ++) poss
            f (x:xs) = do
                y <- globFileTest x
                if null y then f xs else return y

            exts2 = "" : if hasExtension file then [] else exts
            poss = [d </> file <.> e | d <- dirs, e <- exts2]

    globFileTest :: FilePath -> IO [FilePath]
    globFileTest file = do
        (dir,fil) <- return $ splitFileName file
        if '*' `notElem` fil then do
            b <- doesFileExist file
            return [file | b]
         else do
            s <- getDirectoryContents $ dropTrailingPathSeparator dir
            concatMapM (f dir fil) s
        where
            f dir fil x = do
                let dirx = dir </> x
                b <- doesFileExist dirx
                return [dirx | b && globMatch fil x]

    globMatch :: String -> String -> Bool
    globMatch glob s | null glob = False
                     | otherwise =
            head matches `isPrefixOf` s2 && last matches `isSuffixOf` s2 && f matches s2
        where
            norm = if searchPathSeparator == ';' then lower else id
            s2 = norm s
            matches = split '*' $ norm glob

            f []     s  = True
            f (m:ms) [] = False
            f (m:ms) s  | m `isPrefixOf` s = f ms $ drop (length m) s
                        | otherwise = f (m:ms) (tail s)

    -- check for existence and crash if not
    globDir :: FilePath -> IO FilePath
    globDir x = do
        x <- canonicalizePath x
        b <- doesDirectoryExist x
        if b then return x else
            exitMessage ["Could not find directory:"
                        , "    " ++ x]