{-# OPTIONS_GHC -cpp #-}
-- Copyright (C) 2005 David Roundy
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation; either version 2, or (at your option)
-- any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program; see the file COPYING.  If not, write to
-- the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-- Boston, MA 02110-1301, USA.

module Darcs.FilePathUtils ( absolute_dir, just_dir, drop_paths, (///) ) where

import Data.Maybe ( catMaybes )

import System.Directory ( doesDirectoryExist )
import Darcs.Utils ( withCurrentDirectory )
import Workaround ( getCurrentDirectory )
import Darcs.URL ( is_ssh_nopath )
import UglyFileName ( fn2fp, fp2fn, norm_path )
import Darcs.URL ( is_relative )

-- WARNING, WARNING, WARNING!!!!

-- This file is deprecated in favor of the newer Darcs.RepoPath.  It's
-- still got a few functions, which are gradually being moved
-- elsewhere.  Please do not add new functions here, and if possible,
-- avoid using these functions in new places.

absolute_dir :: FilePath -> IO FilePath
absolute_dir dir = do
  isdir <- doesDirectoryExist dir
  if not isdir
     then if is_ssh_nopath dir
            then return $ dir++"."
            else return $ if (take 1 $ reverse dir) == "/"
              then init dir
              else dir
             -- hope it's an URL
     else do
          realdir <- withCurrentDirectory dir getCurrentDirectory
                     -- This one is absolute!
          return realdir

drop_paths :: String -> [String] -> [String]
drop_paths "" ps = map norm_relative ps
    where norm_relative f | is_relative f = do_norm f
                          | otherwise = f
drop_paths fix ps = catMaybes $ map drop_path ps
  where drop_path p | not $ is_relative p = Just p
        drop_path ('.':'/':p) = drop_path $ dropWhile (=='/') p
        drop_path p = if take (length fix) p == fix
                      then Just $ dropWhile (=='/') $ drop (length fix) p
                      else if is_relative p
                           then Nothing
                           else Just p

just_dir :: FilePath -> FilePath
just_dir d = reverse $ takeWhile (/='/') $ reverse d

(///) :: FilePath -> FilePath -> FilePath
""///a = do_norm a
a///b = do_norm $ a ++ "/" ++ b

do_norm :: FilePath -> FilePath
do_norm f = fn2fp $ norm_path $ fp2fn f
