module Manatee.Toolkit.Data.Unique where
import Control.Arrow
import Data.List
import Manatee.Toolkit.General.Basic
import Manatee.Toolkit.General.FilePath
import Manatee.Toolkit.General.List
import System.FilePath
import qualified Data.Map as M
unique :: [FilePath] -> [(FilePath, FilePath)]
unique filePathList =
zip fnl
$ map snd
$ M.toList
$ M.fromList
$ map swap
$ concatMap uniqueDiff
(uniqueGroup (pairPred fpl) uniquePick)
where fpl = map dropTrailingPathSeparator filePathList
fnl = map takeFileNameExceptRoot fpl
uniqueDiff :: [(FilePath, Int)] -> [(FilePath, Int)]
uniqueDiff (xs:[]) = [first (const "") xs]
uniqueDiff list = concatMap uniqueDiffInternal (uniqueGroup list uniquePick_)
uniqueDiffInternal :: [(FilePath, Int)] -> [(FilePath, Int)]
uniqueDiffInternal [] = []
uniqueDiffInternal (xs:[]) = [first getUpperDirectoryName xs]
uniqueDiffInternal list =
map (\(a,b) -> (uniqueMinDiffDir a (uniqueCommon $ map fst list), b)) list
uniqueMinDiffDir :: FilePath -> FilePath -> FilePath
uniqueMinDiffDir filepath common =
addTrailingPathSeparator $ take (length filepath length common) filepath
uniqueGroup :: [(FilePath, Int)] -> ([(FilePath, Int)] -> [(FilePath, Int)]) -> [[(FilePath, Int)]]
uniqueGroup [] _ = []
uniqueGroup list@(_:[]) _ = group list
uniqueGroup list@(_:xs) f = pl : uniqueGroup ys f
where
pl = f list
ys = if length pl == 1
then xs
else (\\) list pl
uniquePick :: [(FilePath, Int)] -> [(FilePath, Int)]
uniquePick [] = []
uniquePick (x:[]) = [x]
uniquePick (x@(a,_):y@(b,_):ys)
| takeFileName a == takeFileName b
= x : uniquePick (y:ys)
| otherwise
= uniquePick (x : ys)
uniquePick_ :: [(FilePath, Int)] -> [(FilePath, Int)]
uniquePick_ [] = []
uniquePick_ (x:[]) = [x]
uniquePick_ (x@(a,_):y@(b,_):ys)
| fileIntersectEnd a b == takeFileName a
= uniquePick_ (x : ys)
| otherwise
= x : uniquePick_ (y:ys)
uniqueCommon :: [FilePath] -> FilePath
uniqueCommon [] = []
uniqueCommon (x:[]) = dropWhile (/= pathSeparator) x
uniqueCommon (x:y:ys) = uniqueCommon (intersectEnd x y : ys)