updateFrameworks :: Options -> VersionTest -> IO ()
updateFrameworks opts rt = when (rt /= VersionAll) $
    mapM_ updateFramework frameworks
  where
    frameworks =
        [ ("/Library/Frameworks/GHC.framework", "Versions", "Current")
        , ("/Library/Haskell", "", "current")
        ]
    updateFramework (fp, vp, cp) = do
        items <- contents $ fp </> vp
        let remain = filter (willKeep cp) items
        let remainVers = reverse . sort . mapMaybe andVersion $ remain

        let curr = fp </> vp </> cp
        currDest <- readSymbolicLink curr `catchIO` (\_ -> return "")
        when (willRemove currDest) $ case (remain, remainVers) of
            ([], _) ->     -- nothing will remain, remove whole framework
                removeDirectoryRecursive opts fp
            (_, []) -> do  -- no versions will remain, but something will
                removeFile opts curr
                message opts $ "** " ++ fp ++
                    " is not empty, but has no more versions. Consider removing."
            (_, ((_,newDest):_)) ->  -- update to maximal remaining version
                symlinkFile opts newDest curr

    willRemove = maybe False (versionTest rt) . partVersion
    willKeep cp fp = notDot fp && (fp /= cp) && (not $ willRemove fp)
    andVersion fp = (\v -> (v, fp)) `fmap` partVersion fp


--
-- Main Operations
--

-- | Display versions found
updateFrameworks :: Options -> VersionTest -> IO ()
updateFrameworks opts rt = when (rt /= VersionAll) $
    mapM_ updateFramework frameworks
  where
    frameworks =
        [ ("/Library/Frameworks/GHC.framework", "Versions", "Current")
        , ("/Library/Haskell", "", "current")
        ]
    updateFramework (fp, vp, cp) = do
        items <- contents $ fp </> vp
        let remain = filter (willKeep cp) items
        let remainVers = reverse . sort . mapMaybe andVersion $ remain

        let curr = fp </> vp </> cp
        currDest <- readSymbolicLink curr `catchIO` (\_ -> return "")
        when (willRemove currDest) $ case (remain, remainVers) of
            ([], _) ->     -- nothing will remain, remove whole framework
                removeDirectoryRecursive opts fp
            (_, []) -> do  -- no versions will remain, but something will
                removeFile opts curr
                message opts $ "** " ++ fp ++
                    " is not empty, but has no more versions. Consider removing."
            (_, ((_,newDest):_)) ->  -- update to maximal remaining version
                symlinkFile opts newDest curr

    willRemove = maybe False (versionTest rt) . partVersion
    willKeep cp fp = notDot fp && (fp /= cp) && (not $ willRemove fp)
    andVersion fp = (\v -> (v, fp)) `fmap` partVersion fp


--
-- Main Operations
--

-- | Display versions found
updateFrameworks opts rt = when (rt /= VersionAll) $
    mapM_ updateFramework frameworks
  where
    frameworks =
        [ ("/Library/Frameworks/GHC.framework", "Versions", "Current")
        , ("/Library/Haskell", "", "current")
        ]
    updateFramework (fp, vp, cp) = do
        items <- contents $ fp </> vp
        let remain = filter (willKeep cp) items
        let remainVers = reverse . sort . mapMaybe andVersion $ remain

        let curr = fp </> vp </> cp
        currDest <- readSymbolicLink curr `catchIO` (\_ -> return "")
        when (willRemove currDest) $ case (remain, remainVers) of
            ([], _) ->     -- nothing will remain, remove whole framework
                removeDirectoryRecursive opts fp
            (_, []) -> do  -- no versions will remain, but something will
                removeFile opts curr
                message opts $ "** " ++ fp ++
                    " is not empty, but has no more versions. Consider removing."
            (_, ((_,newDest):_)) ->  -- update to maximal remaining version
                symlinkFile opts newDest curr

    willRemove = maybe False (versionTest rt) . partVersion
    willKeep cp fp = notDot fp && (fp /= cp) && (not $ willRemove fp)
    andVersion fp = (\v -> (v, fp)) `fmap` partVersion fp


--
-- Main Operations
--

-- | Display versions found