-- | Interface to HackageDB. This module obtains all data from HackageDB needed
--   for searching.
module SearchHackage (withEveryPackage) where

import Control.Monad (foldM, forM, liftM)
import Distribution.Package (PackageIdentifier(..))
import Distribution.PackageDescription
				( PackageDescription )
import Distribution.PackageDescription.Configuration
				( flattenPackageDescription )

import Util (availablePackages, availableVersions, loadPackageDescription)

-- | Folds an action over all package descriptions available on HackageDB.
withEveryPackage :: (a -> PackageDescription -> a) -> a -> IO a
withEveryPackage action a0 = do
	pkgIds <- getAllPackages
	foldM (\a pkgId -> liftM (action a . flattenPackageDescription) $
		loadPackageDescription pkgId) a0 pkgIds

-- | Obtains all packages available on HackageDB.
getAllPackages :: IO [PackageIdentifier]
getAllPackages = do
	names <- availablePackages
	liftM concat $ forM names $ \name -> do
		versions <- availableVersions name
		return $ map (PackageIdentifier name) versions
