module CmdLine.Search(actionSearch) where

import CmdLine.Flag
import CmdLine.Files
import Data.Range
import Data.TagStr
import General.Code
import Hoogle.Query.All
import Hoogle.Search.All
import Hoogle.DataBase.All
import Hoogle.Item.All
import Hoogle.All
import Data.Binary.Defer.Index


actionSearch :: [CmdFlag] -> Query -> IO ()
actionSearch flags q = do
    db <- getDataBaseFiles flags q
    when verbose $
        putStr $ unlines $ "= DATABASES =" : map ("  "++) db

    dbs <- mapM loadDataBase db
    let sug = suggestQuery dbs q
    when (isJust sug) $
        putStrLn $ showTag $ fromJust sug
    when verbose $ putStrLn "= ANSWERS ="

    when (isJust (typeSig q) && color) $ do
        let view = [ArgPosNum i i | i <- [0..10]]
            tags = renderEntryText view $ renderTypeSig $ fromJust $ typeSig q
        putStrLn $ "Searching for: " ++ showTag tags

    let res = search dbs q
    if null res then
        putStrLn "No results found"
     else if Info `elemEnum` flags then do
        let ent = fromLink $ resultEntry $ head res
            pkg = fromLink $ entryPackage ent
        putStrLns 2 $ f $ renderResult $ head res
        putStrLns 2 $ showTag $ renderHaddock $ entryDocs ent
        putStrLn $ "From package " ++ packageName pkg ++ ", version " ++ packageVersion pkg
        putStrLns 1 $ entryURL ent
     else
        putStr $ unlines $ map (f . renderResult) res
    where
        search | start == 0 && count == maxBound = searchAll
               | otherwise = searchRange (rangeStartCount start count)
            where start = headDef 0 [i-1 | Start i <- flags]
                  count = headDef maxBound [i | Count i <- flags]

        verbose = Verbose `elem` flags
        color = Color True `elem` flags
        showTag = if color then showTagConsole else showTagText

        f (m,r,v) = maybe "" (\m -> showModule m ++ " ") m ++
                    showTag r ++ (if verbose then "  -- " ++ v else "")


-- Put out a string with some blank links following
-- Do not put out the blank lines if no text output
putStrLns :: Int -> String -> IO ()
putStrLns n xs = when (xs /= "") $ do
                     putStr xs
                     putStr $ replicate n '\n'