package de.danoeh.antennapod.core.storage;

import android.content.Context;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

import de.danoeh.antennapod.core.R;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.SearchResult;
import de.danoeh.antennapod.core.util.comparator.SearchResultValueComparator;

/**
 * Performs search on Feeds and FeedItems
 */
public class FeedSearcher {
    private static final String TAG = "FeedSearcher";


    /**
     * Search through a feed, or all feeds, for episodes that match the query in either the title,
     * chapter, or show notes. The search is first performed on titles, then chapters, and finally
     * show notes. The list of resulting episodes also describes where the first match occurred
     * (title, chapters, or show notes).
     *
     * @param context
     * @param query search query
     * @param selectedFeed feed to search, 0 to search through all feeds
     * @return list of episodes containing the query
     */
    public static List<SearchResult> performSearch(final Context context,
                                                   final String query, final long selectedFeed) {
        final int values[] = {2, 1, 0, 0};
        final String[] subtitles = {context.getString(R.string.found_in_title_label),
                context.getString(R.string.found_in_chapters_label),
                context.getString(R.string.found_in_shownotes_label),
                context.getString(R.string.found_in_shownotes_label)};

        List<SearchResult> result = new ArrayList<>();

        List<FutureTask<List<FeedItem>>> tasks = new ArrayList<>();
        tasks.add(DBTasks.searchFeedItemTitle(context, selectedFeed, query));
        tasks.add(DBTasks.searchFeedItemChapters(context, selectedFeed, query));
        tasks.add(DBTasks.searchFeedItemDescription(context, selectedFeed, query));
        tasks.add(DBTasks.searchFeedItemContentEncoded(context, selectedFeed, query));

        for (FutureTask<List<FeedItem>> task : tasks) {
            task.run();
        }
        try {
            for (int i = 0; i < tasks.size(); i++) {
                FutureTask<List<FeedItem>> task = tasks.get(i);
                List<FeedItem> items = task.get();
                for (FeedItem item : items) {
                    if (result.isEmpty() || !isDuplicate(result, item)) {
                        result.add(new SearchResult(item, values[i], subtitles[i]));
                    }
                }

            }
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
        Collections.sort(result, new SearchResultValueComparator());
        return result;
    }

    /**
     * Determines if the feed item is already in the search result list.
     *
     * @param result list of search results
     * @param item feed item to validate
     * @return true if the feed item is already in the results
     */
    private static boolean isDuplicate(List<SearchResult> result, FeedItem item) {
        for (SearchResult resultItem : result) {
            if (resultItem.getComponent().getId() == item.getId()) {
                return true;
            }
        }
        return false;
    }
}

@@ -145,19 +145,67 @@
 va.util.
-Lis
+HashSet;%0Aimport java.util.List;%0Aimport java.util.Se
 t;%0Aimpor
@@ -2247,16 +2247,62 @@
   try %7B%0A
+            Set%3CLong%3E set = new HashSet%3C%3E();%0A%0A
         
@@ -2342,24 +2342,24 @@
 e(); i++) %7B%0A
-
             
@@ -2535,40 +2535,62 @@
 if (
-result.isEmpty() %7C%7C !isD
+!set.contains(item.getId())) %7B // to prevent d
 uplicate
 (res
@@ -2589,25 +2589,16 @@
 cate
-(
+ 
 result
-, item)) %7B
+s
 %0A   
@@ -2675,24 +2675,71 @@
 itles%5Bi%5D));%0A
+                        set.add(item.getId());%0A
             
@@ -2762,25 +2762,24 @@
           %7D%0A
-%0A
             
@@ -2952,24 +2952,24 @@
 parator());%0A
+
         retu
@@ -2988,534 +2988,7 @@
    %7D
-%0A%0A    /**%0A     * Determines if the feed item is already in the search result list.%0A     *%0A     * @param result list of search results%0A     * @param item feed item to validate%0A     * @return true if the feed item is already in the results%0A     */%0A    private static boolean isDuplicate(List%3CSearchResult%3E result, FeedItem item) %7B%0A        for (SearchResult resultItem : result) %7B%0A            if (resultItem.getComponent().getId() == item.getId()) %7B%0A                return true;%0A            %7D%0A        %7D%0A        return false;%0A    %7D
 %0A%7D%0A

Improve duplicate removal run time by using a hash set