using Common.Configuration;
using Common.Configuration.Arr;
using Common.Configuration.ContentBlocker;
using Common.Configuration.DownloadCleaner;
using Common.Configuration.DownloadClient;
using Common.Configuration.IgnoredDownloads;
using Common.Configuration.QueueCleaner;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
namespace Infrastructure.Configuration;
///
/// Provides configuration management for various components with thread-safe file access.
///
public interface IConfigurationManager
{
// Configuration files
Task GetConfigurationAsync(string configFileName) where T : class, new();
Task SaveConfigurationAsync(string configFileName, T config) where T : class;
Task UpdateConfigurationPropertyAsync(string configFileName, string propertyPath, T value);
Task MergeConfigurationAsync(string configFileName, T newValues) where T : class;
Task DeleteConfigurationAsync(string configFileName);
IEnumerable ListConfigurationFiles();
// Specific configuration types (for common configs)
Task GetSonarrConfigAsync();
Task GetRadarrConfigAsync();
Task GetLidarrConfigAsync();
Task GetContentBlockerConfigAsync();
Task GetQueueCleanerConfigAsync();
Task GetDownloadCleanerConfigAsync();
Task GetDownloadClientConfigAsync();
Task GetIgnoredDownloadsConfigAsync();
Task SaveSonarrConfigAsync(SonarrConfig config);
Task SaveRadarrConfigAsync(RadarrConfig config);
Task SaveLidarrConfigAsync(LidarrConfig config);
Task SaveContentBlockerConfigAsync(ContentBlockerConfig config);
Task SaveQueueCleanerConfigAsync(QueueCleanerConfig config);
Task SaveDownloadCleanerConfigAsync(DownloadCleanerConfig config);
Task SaveDownloadClientConfigAsync(DownloadClientConfig config);
Task SaveIgnoredDownloadsConfigAsync(IgnoredDownloadsConfig config);
}
public class ConfigurationManager : IConfigurationManager
{
private readonly ILogger _logger;
private readonly JsonConfigurationProvider _configProvider;
private readonly IOptionsMonitor _sonarrConfig;
private readonly IOptionsMonitor _radarrConfig;
private readonly IOptionsMonitor _lidarrConfig;
private readonly IOptionsMonitor _contentBlockerConfig;
private readonly IOptionsMonitor _queueCleanerConfig;
private readonly IOptionsMonitor _downloadCleanerConfig;
private readonly IOptionsMonitor _downloadClientConfig;
private readonly IOptionsMonitor _ignoredDownloadsConfig;
// Define standard config file names
private const string SonarrConfigFile = "sonarr.json";
private const string RadarrConfigFile = "radarr.json";
private const string LidarrConfigFile = "lidarr.json";
private const string ContentBlockerConfigFile = "contentblocker.json";
private const string QueueCleanerConfigFile = "queuecleaner.json";
private const string DownloadCleanerConfigFile = "downloadcleaner.json";
private const string DownloadClientConfigFile = "downloadclient.json";
private const string IgnoredDownloadsConfigFile = "ignoreddownloads.json";
public ConfigurationManager(
ILogger logger,
JsonConfigurationProvider configProvider,
IOptionsMonitor sonarrConfig,
IOptionsMonitor radarrConfig,
IOptionsMonitor lidarrConfig,
IOptionsMonitor contentBlockerConfig,
IOptionsMonitor queueCleanerConfig,
IOptionsMonitor downloadCleanerConfig,
IOptionsMonitor downloadClientConfig,
IOptionsMonitor ignoredDownloadsConfig)
{
_logger = logger;
_configProvider = configProvider;
_sonarrConfig = sonarrConfig;
_radarrConfig = radarrConfig;
_lidarrConfig = lidarrConfig;
_contentBlockerConfig = contentBlockerConfig;
_queueCleanerConfig = queueCleanerConfig;
_downloadCleanerConfig = downloadCleanerConfig;
_downloadClientConfig = downloadClientConfig;
_ignoredDownloadsConfig = ignoredDownloadsConfig;
}
// Generic configuration methods
public Task GetConfigurationAsync(string configFileName) where T : class, new()
{
return _configProvider.ReadConfigurationAsync(configFileName);
}
public Task SaveConfigurationAsync(string configFileName, T config) where T : class
{
// Validate if it's an IConfig
if (config is IConfig configurable)
{
try
{
configurable.Validate();
}
catch (Exception ex)
{
_logger.LogError(ex, "Configuration validation failed for {fileName}", configFileName);
return Task.FromResult(false);
}
}
return _configProvider.WriteConfigurationAsync(configFileName, config);
}
public Task UpdateConfigurationPropertyAsync(string configFileName, string propertyPath, T value)
{
return _configProvider.UpdateConfigurationPropertyAsync(configFileName, propertyPath, value);
}
public Task MergeConfigurationAsync(string configFileName, T newValues) where T : class
{
return _configProvider.MergeConfigurationAsync(configFileName, newValues);
}
public Task DeleteConfigurationAsync(string configFileName)
{
return _configProvider.DeleteConfigurationAsync(configFileName);
}
public IEnumerable ListConfigurationFiles()
{
return _configProvider.ListConfigurationFiles();
}
// Specific configuration type methods
public async Task GetSonarrConfigAsync()
{
var config = await _configProvider.ReadConfigurationAsync(SonarrConfigFile);
return config ?? _sonarrConfig.CurrentValue;
}
public async Task GetRadarrConfigAsync()
{
var config = await _configProvider.ReadConfigurationAsync(RadarrConfigFile);
return config ?? _radarrConfig.CurrentValue;
}
public async Task GetLidarrConfigAsync()
{
var config = await _configProvider.ReadConfigurationAsync(LidarrConfigFile);
return config ?? _lidarrConfig.CurrentValue;
}
public async Task GetContentBlockerConfigAsync()
{
var config = await _configProvider.ReadConfigurationAsync(ContentBlockerConfigFile);
return config ?? _contentBlockerConfig.CurrentValue;
}
public async Task GetQueueCleanerConfigAsync()
{
var config = await _configProvider.ReadConfigurationAsync(QueueCleanerConfigFile);
return config ?? _queueCleanerConfig.CurrentValue;
}
public async Task GetDownloadCleanerConfigAsync()
{
var config = await _configProvider.ReadConfigurationAsync(DownloadCleanerConfigFile);
return config ?? _downloadCleanerConfig.CurrentValue;
}
public async Task GetDownloadClientConfigAsync()
{
var config = await _configProvider.ReadConfigurationAsync(DownloadClientConfigFile);
return config ?? _downloadClientConfig.CurrentValue;
}
public Task SaveSonarrConfigAsync(SonarrConfig config)
{
try
{
config.Validate();
return _configProvider.WriteConfigurationAsync(SonarrConfigFile, config);
}
catch (Exception ex)
{
_logger.LogError(ex, "Sonarr configuration validation failed");
return Task.FromResult(false);
}
}
public Task SaveRadarrConfigAsync(RadarrConfig config)
{
try
{
config.Validate();
return _configProvider.WriteConfigurationAsync(RadarrConfigFile, config);
}
catch (Exception ex)
{
_logger.LogError(ex, "Radarr configuration validation failed");
return Task.FromResult(false);
}
}
public Task SaveLidarrConfigAsync(LidarrConfig config)
{
try
{
config.Validate();
return _configProvider.WriteConfigurationAsync(LidarrConfigFile, config);
}
catch (Exception ex)
{
_logger.LogError(ex, "Lidarr configuration validation failed");
return Task.FromResult(false);
}
}
public Task SaveContentBlockerConfigAsync(ContentBlockerConfig config)
{
try
{
config.Validate();
return _configProvider.WriteConfigurationAsync(ContentBlockerConfigFile, config);
}
catch (Exception ex)
{
_logger.LogError(ex, "ContentBlocker configuration validation failed");
return Task.FromResult(false);
}
}
public Task SaveQueueCleanerConfigAsync(QueueCleanerConfig config)
{
try
{
config.Validate();
return _configProvider.WriteConfigurationAsync(QueueCleanerConfigFile, config);
}
catch (Exception ex)
{
_logger.LogError(ex, "QueueCleaner configuration validation failed");
return Task.FromResult(false);
}
}
public Task SaveDownloadCleanerConfigAsync(DownloadCleanerConfig config)
{
try
{
config.Validate();
return _configProvider.WriteConfigurationAsync(DownloadCleanerConfigFile, config);
}
catch (Exception ex)
{
_logger.LogError(ex, "DownloadCleaner configuration validation failed");
return Task.FromResult(false);
}
}
public Task SaveDownloadClientConfigAsync(DownloadClientConfig config)
{
try
{
config.Validate();
return _configProvider.WriteConfigurationAsync(DownloadClientConfigFile, config);
}
catch (Exception ex)
{
_logger.LogError(ex, "DownloadClient configuration validation failed");
return Task.FromResult(false);
}
}
public async Task GetIgnoredDownloadsConfigAsync()
{
var config = await _configProvider.ReadConfigurationAsync(IgnoredDownloadsConfigFile);
return config ?? _ignoredDownloadsConfig.CurrentValue;
}
public Task SaveIgnoredDownloadsConfigAsync(IgnoredDownloadsConfig config)
{
try
{
return _configProvider.WriteConfigurationAsync(IgnoredDownloadsConfigFile, config);
}
catch (Exception ex)
{
_logger.LogError(ex, "IgnoredDownloads configuration save failed");
return Task.FromResult(false);
}
}
}