using FinlyticAssets.Database;
using FinlyticAssets.Entities;
using Microsoft.EntityFrameworkCore;
namespace FinlyticAssets.Services;
///
/// Defines the business logic for managing global application settings.
/// Supports retrieving and updating (upserting) the central single-row configuration record.
///
public interface ISettingsDbService
{
///
/// Retrieves the current global settings from the database.
///
///
/// A task that represents the asynchronous operation. The task result contains the current .
/// If no settings exist in the database yet, a new instance initialized with default values is returned.
///
public Task GetSettings();
///
/// Persists the provided settings by updating the existing record or inserting the first one if the table is empty.
///
/// The new configuration values to be persisted.
///
/// A task that represents the asynchronous operation. The task result contains the freshly saved
/// and tracked instance.
///
public Task SaveSettings(Settings settings);
///
/// Updates settings from a key-value dictionary received via Admin Panel MQTT events.
///
public Task UpdateSettingsFromDictionary(Dictionary dictionary);
}
///
/// Implements the utilizing Entity Framework Core.
/// This service is designed for a single-row table architecture to maintain stateful global configurations.
///
public class SettingsDbService : ISettingsDbService
{
private readonly AssetsDbContext _context;
///
/// Initializes a new instance of the class with the required database context.
///
/// The EF Core context used to access the assets database.
public SettingsDbService(AssetsDbContext context)
{
_context = context;
}
/// Inherits documentation from interface.
public async Task GetSettings()
{
var settings = await _context.Settings.AsNoTracking().FirstOrDefaultAsync();
if (settings == null)
{
settings = new Settings { Id = Guid.NewGuid() };
_context.Settings.Add(settings);
await _context.SaveChangesAsync();
_context.ChangeTracker.Clear();
}
return settings;
}
/// Inherits documentation from interface.
public async Task SaveSettings(Settings settings)
{
var existing = await _context.Settings.FirstOrDefaultAsync();
if (existing == null)
{
if (settings.Id == Guid.Empty)
{
settings.Id = Guid.NewGuid();
}
_context.Settings.Add(settings);
await _context.SaveChangesAsync();
return settings;
}
else
{
existing.FinishedInitialScan = settings.FinishedInitialScan;
existing.TradeRepublicMaxRequestPageSize = settings.TradeRepublicMaxRequestPageSize;
existing.AssetUpdateTypeDelay = settings.AssetUpdateTypeDelay;
existing.InitAssetUpdateTypeDelay = settings.InitAssetUpdateTypeDelay;
existing.InitBatchAssetUpdateDelay = settings.InitBatchAssetUpdateDelay;
existing.BatchAssetUpdateDelay = settings.BatchAssetUpdateDelay;
existing.CurrentScanningType = settings.CurrentScanningType;
existing.CurrentScanningPage = settings.CurrentScanningPage;
_context.Settings.Update(existing);
await _context.SaveChangesAsync();
return existing;
}
}
/// Inherits documentation from interface.
public async Task UpdateSettingsFromDictionary(Dictionary dictionary)
{
var settings = await GetSettings();
foreach (var (key, value) in dictionary)
{
if (string.Equals(key, "TradeRepublicMaxRequestPageSize", StringComparison.OrdinalIgnoreCase) && int.TryParse(value, out var ps))
settings.TradeRepublicMaxRequestPageSize = ps;
else if (string.Equals(key, "AssetUpdateTypeDelay", StringComparison.OrdinalIgnoreCase) && int.TryParse(value, out var autd))
settings.AssetUpdateTypeDelay = autd;
else if (string.Equals(key, "InitAssetUpdateTypeDelay", StringComparison.OrdinalIgnoreCase) && int.TryParse(value, out var iautd))
settings.InitAssetUpdateTypeDelay = iautd;
else if (string.Equals(key, "BatchAssetUpdateDelay", StringComparison.OrdinalIgnoreCase) && int.TryParse(value, out var baud))
settings.BatchAssetUpdateDelay = baud;
else if (string.Equals(key, "InitBatchAssetUpdateDelay", StringComparison.OrdinalIgnoreCase) && int.TryParse(value, out var ibaud))
settings.InitBatchAssetUpdateDelay = ibaud;
else if (string.Equals(key, "FinishedInitialScan", StringComparison.OrdinalIgnoreCase) && bool.TryParse(value, out var fis))
settings.FinishedInitialScan = fis;
}
await SaveSettings(settings);
}
}