package org.mafagafogigante.dungeon.wiki; import org.mafagafogigante.dungeon.game.DungeonString; import org.mafagafogigante.dungeon.io.Writer; import org.mafagafogigante.dungeon.util.CounterMap; import org.mafagafogigante.dungeon.util.Matches; import org.apache.commons.lang3.StringUtils; import java.util.Locale; /** * Uninstantiable WikiSearcher class used to retrieve articles from the Wiki. */ public final class WikiSearcher { private WikiSearcher() { throw new AssertionError(); } /** * Searches the wiki and writes the matching contents to the screen. This method triggers the wiki initialization. * * @param arguments an array of arguments that will determine the search */ public static void search(String[] arguments) { if (arguments.length != 0) { Matches<Article> matches = Matches.findBestMatches(Wiki.getArticles(), arguments); if (matches.size() == 0) { deepSearch(arguments); } else if (matches.size() == 1) { Writer.write(matches.getMatch(0).toString()); } else { DungeonString string = new DungeonString(); string.append("The following article titles match your query:\n"); for (int i = 0; i < matches.size(); i++) { string.append(toArticleListingEntry(matches.getMatch(i))); string.append("\n"); } string.append("Be more specific."); Writer.write(string); } } else { writeArticleList(); } } /** * Searches the wiki by looking at the content of the articles. * * @param arguments an array of arguments that will determine the search */ private static void deepSearch(String[] arguments) { CounterMap<Article> counter = new CounterMap<>(); for (Article article : Wiki.getArticles()) { int matches = 0; for (String argument : arguments) { final String lowerCaseArticleContent = article.getContent().toLowerCase(Locale.ENGLISH); final String lowerCaseArgument = argument.toLowerCase(Locale.ENGLISH); matches += StringUtils.countMatches(lowerCaseArticleContent, lowerCaseArgument); } if (matches != 0) { counter.incrementCounter(article, matches); } } DungeonString string = new DungeonString(); if (counter.isNotEmpty()) { string.append("The following articles contain text that matches your query:\n"); for (Article article : counter) { String matchCount = counter.getCounter(article) + (counter.getCounter(article) > 1 ? " matches" : " match"); string.append(toArticleListingEntry(article) + " (" + matchCount + ")\n"); } } else { string.append("No article matches your query."); } Writer.write(string); } /** * Writes the article count and a list with the titles of the {@code Articles} in the {@code articleList}. */ private static void writeArticleList() { DungeonString string = new DungeonString(); string.append("The wiki has the following "); string.append(String.valueOf(Wiki.getArticles().size())); string.append(" articles:\n"); for (Article article : Wiki.getArticles()) { string.append(toArticleListingEntry(article)); string.append("\n"); } Writer.write(string); } private static String toArticleListingEntry(Article article) { return " " + article.getName(); } }