From b845268b3d67bcc1f8075ff508dff5f57fc41bc4 Mon Sep 17 00:00:00 2001
From: Mark McDowall <mark@mcdowall.ca>
Date: Fri, 22 Nov 2024 18:39:35 -0800
Subject: [PATCH] New: Support for new SABnzbd history retention values

Closes #10699

(cherry picked from commit e361f18837d98c089f7dc9c0190221ca8e2cf225)
---
 .../SabnzbdTests/SabnzbdFixture.cs            | 31 +++++++++++
 .../Download/Clients/Sabnzbd/Sabnzbd.cs       | 53 ++++++++++++++-----
 .../Clients/Sabnzbd/SabnzbdCategory.cs        |  2 +
 3 files changed, 72 insertions(+), 14 deletions(-)

diff --git a/src/NzbDrone.Core.Test/Download/DownloadClientTests/SabnzbdTests/SabnzbdFixture.cs b/src/NzbDrone.Core.Test/Download/DownloadClientTests/SabnzbdTests/SabnzbdFixture.cs
index fe782f0c9..00d904a0a 100644
--- a/src/NzbDrone.Core.Test/Download/DownloadClientTests/SabnzbdTests/SabnzbdFixture.cs
+++ b/src/NzbDrone.Core.Test/Download/DownloadClientTests/SabnzbdTests/SabnzbdFixture.cs
@@ -478,6 +478,37 @@ public void should_set_history_removes_completed_downloads_true(string historyRe
             downloadClientInfo.RemovesCompletedDownloads.Should().BeTrue();
         }
 
+        [TestCase("all", 0)]
+        [TestCase("days-archive", 15)]
+        [TestCase("days-delete", 15)]
+        public void should_set_history_removes_completed_downloads_false_for_separate_properties(string option, int number)
+        {
+            _config.Misc.history_retention_option = option;
+            _config.Misc.history_retention_number = number;
+
+            var downloadClientInfo = Subject.GetStatus();
+
+            downloadClientInfo.RemovesCompletedDownloads.Should().BeFalse();
+        }
+
+        [TestCase("number-archive", 10)]
+        [TestCase("number-delete", 10)]
+        [TestCase("number-archive", 0)]
+        [TestCase("number-delete", 0)]
+        [TestCase("days-archive", 3)]
+        [TestCase("days-delete", 3)]
+        [TestCase("all-archive", 0)]
+        [TestCase("all-delete", 0)]
+        public void should_set_history_removes_completed_downloads_true_for_separate_properties(string option, int number)
+        {
+            _config.Misc.history_retention_option = option;
+            _config.Misc.history_retention_number = number;
+
+            var downloadClientInfo = Subject.GetStatus();
+
+            downloadClientInfo.RemovesCompletedDownloads.Should().BeTrue();
+        }
+
         [TestCase(@"Y:\sabnzbd\root", @"completed\downloads", @"vv", @"Y:\sabnzbd\root\completed\downloads", @"Y:\sabnzbd\root\completed\downloads\vv")]
         [TestCase(@"Y:\sabnzbd\root", @"completed", @"vv", @"Y:\sabnzbd\root\completed", @"Y:\sabnzbd\root\completed\vv")]
         [TestCase(@"/sabnzbd/root", @"completed/downloads", @"vv", @"/sabnzbd/root/completed/downloads", @"/sabnzbd/root/completed/downloads/vv")]
diff --git a/src/NzbDrone.Core/Download/Clients/Sabnzbd/Sabnzbd.cs b/src/NzbDrone.Core/Download/Clients/Sabnzbd/Sabnzbd.cs
index 7237640ad..02e8a17ef 100644
--- a/src/NzbDrone.Core/Download/Clients/Sabnzbd/Sabnzbd.cs
+++ b/src/NzbDrone.Core/Download/Clients/Sabnzbd/Sabnzbd.cs
@@ -278,20 +278,7 @@ public override DownloadClientInfo GetStatus()
                 status.OutputRootFolders = new List<OsPath> { _remotePathMappingService.RemapRemoteToLocal(Settings.Host, category.FullPath) };
             }
 
-            if (config.Misc.history_retention.IsNullOrWhiteSpace())
-            {
-                status.RemovesCompletedDownloads = false;
-            }
-            else if (config.Misc.history_retention.EndsWith("d"))
-            {
-                int.TryParse(config.Misc.history_retention.AsSpan(0, config.Misc.history_retention.Length - 1),
-                    out var daysRetention);
-                status.RemovesCompletedDownloads = daysRetention < 14;
-            }
-            else
-            {
-                status.RemovesCompletedDownloads = config.Misc.history_retention != "0";
-            }
+            status.RemovesCompletedDownloads = RemovesCompletedDownloads(config);
 
             return status;
         }
@@ -548,6 +535,44 @@ private bool ContainsCategory(IEnumerable<string> categories, string category)
             return categories.Contains(category);
         }
 
+        private bool RemovesCompletedDownloads(SabnzbdConfig config)
+        {
+            var retention = config.Misc.history_retention;
+            var option = config.Misc.history_retention_option;
+            var number = config.Misc.history_retention_number;
+
+            switch (option)
+            {
+                case "all":
+                    return false;
+                case "number-archive":
+                case "number-delete":
+                    return true;
+                case "days-archive":
+                case "days-delete":
+                    return number < 14;
+                case "all-archive":
+                case "all-delete":
+                    return true;
+            }
+
+            // TODO: Remove these checks once support for SABnzbd < 4.3 is removed
+
+            if (retention.IsNullOrWhiteSpace())
+            {
+                return false;
+            }
+
+            if (retention.EndsWith("d"))
+            {
+                int.TryParse(config.Misc.history_retention.AsSpan(0, config.Misc.history_retention.Length - 1),
+                    out var daysRetention);
+                return daysRetention < 14;
+            }
+
+            return retention != "0";
+        }
+
         private bool ValidatePath(DownloadClientItem downloadClientItem)
         {
             var downloadItemOutputPath = downloadClientItem.OutputPath;
diff --git a/src/NzbDrone.Core/Download/Clients/Sabnzbd/SabnzbdCategory.cs b/src/NzbDrone.Core/Download/Clients/Sabnzbd/SabnzbdCategory.cs
index aa04edc5d..740b34ddb 100644
--- a/src/NzbDrone.Core/Download/Clients/Sabnzbd/SabnzbdCategory.cs
+++ b/src/NzbDrone.Core/Download/Clients/Sabnzbd/SabnzbdCategory.cs
@@ -32,6 +32,8 @@ public class SabnzbdConfigMisc
         public bool enable_date_sorting { get; set; }
         public bool pre_check { get; set; }
         public string history_retention { get; set; }
+        public string history_retention_option { get; set; }
+        public int history_retention_number { get; set; }
     }
 
     public class SabnzbdCategory