From e1656636164bf040624fd4ff2605f3d4e7b06156 Mon Sep 17 00:00:00 2001
From: Mark McDowall <mark@mcdowall.ca>
Date: Fri, 15 Jan 2021 17:24:19 -0800
Subject: [PATCH] Fixed: Sorting in Interactive search duplicates results

(cherry picked from commit a6637b2911f7818e596c1518e94bd111cff0120b)

Closes #739
Closes #743
---
 .../IndexerSearch/ReleaseSearchService.cs     | 22 +++++++++++++++++--
 1 file changed, 20 insertions(+), 2 deletions(-)

diff --git a/src/NzbDrone.Core/IndexerSearch/ReleaseSearchService.cs b/src/NzbDrone.Core/IndexerSearch/ReleaseSearchService.cs
index 63962502b..edcd34442 100644
--- a/src/NzbDrone.Core/IndexerSearch/ReleaseSearchService.cs
+++ b/src/NzbDrone.Core/IndexerSearch/ReleaseSearchService.cs
@@ -43,14 +43,26 @@ namespace NzbDrone.Core.IndexerSearch
 
         public List<DownloadDecision> BookSearch(int bookId, bool missingOnly, bool userInvokedSearch, bool interactiveSearch)
         {
+            var downloadDecisions = new List<DownloadDecision>();
+
             var book = _bookService.GetBook(bookId);
-            return BookSearch(book, missingOnly, userInvokedSearch, interactiveSearch);
+
+            var decisions = BookSearch(book, missingOnly, userInvokedSearch, interactiveSearch);
+            downloadDecisions.AddRange(decisions);
+
+            return DeDupeDecisions(downloadDecisions);
         }
 
         public List<DownloadDecision> AuthorSearch(int authorId, bool missingOnly, bool userInvokedSearch, bool interactiveSearch)
         {
+            var downloadDecisions = new List<DownloadDecision>();
+
             var author = _authorService.GetAuthor(authorId);
-            return AuthorSearch(author, missingOnly, userInvokedSearch, interactiveSearch);
+
+            var decisions = AuthorSearch(author, missingOnly, userInvokedSearch, interactiveSearch);
+            downloadDecisions.AddRange(decisions);
+
+            return DeDupeDecisions(downloadDecisions);
         }
 
         public List<DownloadDecision> AuthorSearch(Author author, bool missingOnly, bool userInvokedSearch, bool interactiveSearch)
@@ -150,5 +162,11 @@ namespace NzbDrone.Core.IndexerSearch
 
             return _makeDownloadDecision.GetSearchDecision(reports, criteriaBase).ToList();
         }
+
+        private List<DownloadDecision> DeDupeDecisions(List<DownloadDecision> decisions)
+        {
+            // De-dupe reports by guid so duplicate results aren't returned. Pick the one with the least rejections.
+            return decisions.GroupBy(d => d.RemoteBook.Release.Guid).Select(d => d.OrderBy(v => v.Rejections.Count()).First()).ToList();
+        }
     }
 }