    module Hoogle.DataBase.All
        (DataBase, showDataBase
        ,module Hoogle.DataBase.All
        ,module Hoogle.DataBase.Serialise
        ) where

    import Hoogle.Store.All
    import Data.Monoid
    import Hoogle.DataBase.Type
    import Hoogle.Type.All
    import Hoogle.Score.All
    import Hoogle.DataBase.Serialise

    createDataBase :: [DataBase] -> Input -> DataBase
    createDataBase deps (facts,xs) = DataBase items
            ns (createTypeSearch as is tys)
            (createSuggest (map suggest deps) facts) as is
        where
            items = createItems xs
            ys = entriesItems items
            ns = createSubstrSearch [(k, y) | y <- ys, let k = entryKey $ fromOnce y, k /= ""]
            as = createAliases (map aliases deps) facts
            is = createInstances (map instances deps) facts
            tys = [(sig, x) | x <- ys, Just sig <- [entryType $ fromOnce x]]

    combineDataBase :: [DataBase] -> DataBase
    combineDataBase [db] = db
    combineDataBase dbs = DataBase items_
            ns (createTypeSearch as is tys)
            ss as is
        where
            items_ = mconcat $ map items dbs
            ys = entriesItems items_
            ns = createSubstrSearch [(entryKey $ fromOnce y, y) | y <- ys]
            ss = mconcat $ map suggest dbs
            as = mconcat $ map aliases dbs
            is = mconcat $ map instances dbs
            tys = [(sig, x) | x <- ys, Just sig <- [entryType $ fromOnce x]]

    searchName :: DataBase -> String -> [(Once Entry,EntryView,Score)]
    searchName db = searchSubstrSearch (nameSearch db)

    searchExactName :: ItemKind -> DataBase -> String -> [(Once Entry,EntryView,Score)]
    searchExactName kind db = filter' . searchExactSearch (nameSearch db)
      where filter' = if kind == UnclassifiedItem
                      then id
                      else filter (\(ent,_,_) -> kind == entryKind (fromOnce ent))

    searchType :: DataBase -> TypeSig -> [(Once Entry,[EntryView],Score)]
    -- although aliases and instances are given, they are usually not used
    searchType db = searchTypeSearch (aliases db) (instances db) (typeSearch db)

    suggestion :: [DataBase] -> TypeSig -> Maybe (Either String TypeSig)
    suggestion db = askSuggest (map suggest db)

    completions :: DataBase -> String -> [String]
    completions db = completionsSubstrSearch (nameSearch db)