-- -- | Print the documentation of a name in the given module.
searchAndPrintDoc
  :: [String]          -- ^ GHC Options
  -> Bool              -- ^ Print modules only.
  -> Bool              -- ^ S-expression format.
  -> Maybe PackageName -- ^ Package.
  -> Maybe ModuleName  -- ^ Module name.
  -> Identifier        -- ^ Identifier.
  -> Ghc ()
searchAndPrintDoc flags _ms ss _pname _mname ident =
  do result <- liftIO (lookupIdent flags
                                   (T.pack (unIdentifier ident)))
     case result of
       Nothing -> throw NoFindModule
       Just pkgModuleMap ->
         do pkgs <- getAllPackages flags
            docs <- fmap concat
                         (forM (M.toList pkgModuleMap)
                               (searchResult pkgs))
            if ss
               then printSexp docs
               else mapM_ (\(_,doc') ->
                             printIdentDoc False True True doc')
                          (zip [0 :: Int ..]
                               (nub docs))
  where searchResult pkgs (pkgName,modName) =
          case find (matchingPkg pkgName) pkgs of
            Nothing -> return []
            Just pkg -> searchPkg pkg modName
          where matchingPkg pkgNm = (== pkgNm) . T.pack . showPackageName .
                                    getIdentifier
        searchPkg pkg modName =
          do result <- searchWithPackage
                         pkg
                         (Just (head (fmap (makeModuleName . T.unpack) modName)))
                         ident
             case result of
               Left err -> throw err
               Right (sortBy (comparing identDocPackageName) -> docs) -> return docs

-- | Search only for identifiers and print out all modules associated.
searchAndPrintDoc
  :: [String]          -- ^ GHC Options
  -> Bool              -- ^ Print modules only.
  -> Bool              -- ^ S-expression format.
  -> Maybe PackageName -- ^ Package.
  -> Maybe ModuleName  -- ^ Module name.
  -> Identifier        -- ^ Identifier.
  -> Ghc ()
searchAndPrintDoc flags _ms ss _pname _mname ident =
  do result <- liftIO (lookupIdent flags
                                   (T.pack (unIdentifier ident)))
     case result of
       Nothing -> throw NoFindModule
       Just pkgModuleMap ->
         do pkgs <- getAllPackages flags
            docs <- fmap concat
                         (forM (M.toList pkgModuleMap)
                               (searchResult pkgs))
            if ss
               then printSexp docs
               else mapM_ (\(_,doc') ->
                             printIdentDoc False True True doc')
                          (zip [0 :: Int ..]
                               (nub docs))
  where searchResult pkgs (pkgName,modName) =
          case find (matchingPkg pkgName) pkgs of
            Nothing -> return []
            Just pkg -> searchPkg pkg modName
          where matchingPkg pkgNm = (== pkgNm) . T.pack . showPackageName .
                                    getIdentifier
        searchPkg pkg modName =
          do result <- searchWithPackage
                         pkg
                         (Just (head (fmap (makeModuleName . T.unpack) modName)))
                         ident
             case result of
               Left err -> throw err
               Right (sortBy (comparing identDocPackageName) -> docs) -> return docs

-- | Search only for identifiers and print out all modules associated.
searchAndPrintDoc flags _ms ss _pname _mname ident =
  do result <- liftIO (lookupIdent flags
                                   (T.pack (unIdentifier ident)))
     case result of
       Nothing -> throw NoFindModule
       Just pkgModuleMap ->
         do pkgs <- getAllPackages flags
            docs <- fmap concat
                         (forM (M.toList pkgModuleMap)
                               (searchResult pkgs))
            if ss
               then printSexp docs
               else mapM_ (\(_,doc') ->
                             printIdentDoc False True True doc')
                          (zip [0 :: Int ..]
                               (nub docs))
  where searchResult pkgs (pkgName,modName) =
          case find (matchingPkg pkgName) pkgs of
            Nothing -> return []
            Just pkg -> searchPkg pkg modName
          where matchingPkg pkgNm = (== pkgNm) . T.pack . showPackageName .
                                    getIdentifier
        searchPkg pkg modName =
          do result <- searchWithPackage
                         pkg
                         (Just (head (fmap (makeModuleName . T.unpack) modName)))
                         ident
             case result of
               Left err -> throw err
               Right (sortBy (comparing identDocPackageName) -> docs) -> return docs

-- | Search only for identifiers and print out all modules associated.