using DataModel.Database; using DataModel.Database.Common; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; namespace Processor; public static class AppSettings { #region DeepL Settings #region DeepL Mode private static SettingDeepLMode CACHE_DEEPL_MODE = SettingDeepLMode.DISABLED; private static bool CACHE_DEEPL_MODE_IS_LOADED = false; public static async Task SetDeepLMode(SettingDeepLMode mode) { // Convert the enum to its int value: var intValue = (int)mode; // Update the cache: CACHE_DEEPL_MODE = mode; CACHE_DEEPL_MODE_IS_LOADED = true; // Get the database: await using var db = ProcessorMeta.ServiceProvider.GetRequiredService(); // Check, if the setting is already set: if (await db.Settings.FirstOrDefaultAsync(n => n.Code == SettingNames.DEEPL_MODE) is {} existingSetting) { existingSetting.IntegerValue = intValue; await db.SaveChangesAsync(); } // Does not exist, so create it: else { var setting = new Setting { Code = SettingNames.DEEPL_MODE, IntegerValue = intValue, }; await db.Settings.AddAsync(setting); await db.SaveChangesAsync(); } } public static async Task GetDeepLMode() { if (CACHE_DEEPL_MODE_IS_LOADED) return CACHE_DEEPL_MODE; var mode = SettingDeepLMode.DISABLED; try { // Get the database: await using var db = ProcessorMeta.ServiceProvider.GetRequiredService(); // Check, if the setting is already set: if (await db.Settings.FirstOrDefaultAsync(n => n.Code == SettingNames.DEEPL_MODE) is { } existingSetting) { mode = (SettingDeepLMode) existingSetting.IntegerValue; return mode; } // Does not exist, so create it: var setting = new Setting { Code = SettingNames.DEEPL_MODE, IntegerValue = (int) mode, }; await db.Settings.AddAsync(setting); await db.SaveChangesAsync(); return mode; } finally { CACHE_DEEPL_MODE = mode; CACHE_DEEPL_MODE_IS_LOADED = true; } } #endregion #region DeepL API Key private static string CACHE_DEEPL_API_KEY = string.Empty; private static bool CACHE_DEEPL_API_KEY_IS_LOADED = false; public static async Task SetDeepLAPIKey(string apiKey) { // Update the cache: CACHE_DEEPL_API_KEY = apiKey; CACHE_DEEPL_API_KEY_IS_LOADED = true; // Get the database: await using var db = ProcessorMeta.ServiceProvider.GetRequiredService(); // Check, if the setting is already set: if (await db.Settings.FirstOrDefaultAsync(n => n.Code == SettingNames.DEEPL_API_KEY) is {} existingSetting) { existingSetting.TextValue = apiKey; await db.SaveChangesAsync(); } // Does not exist, so create it: else { var setting = new Setting { Code = SettingNames.DEEPL_API_KEY, TextValue = apiKey, }; await db.Settings.AddAsync(setting); await db.SaveChangesAsync(); } } public static async Task GetDeepLAPIKey() { // Check the cache: if (CACHE_DEEPL_API_KEY_IS_LOADED) return CACHE_DEEPL_API_KEY; var key = string.Empty; try { // Get the database: await using var db = ProcessorMeta.ServiceProvider.GetRequiredService(); // Check, if the setting is already set: if (await db.Settings.FirstOrDefaultAsync(n => n.Code == SettingNames.DEEPL_API_KEY) is { } existingSetting) { key = existingSetting.TextValue; return key; } // Does not exist, so create it: var setting = new Setting { Code = SettingNames.DEEPL_API_KEY, TextValue = key, }; await db.Settings.AddAsync(setting); await db.SaveChangesAsync(); return key; } finally { CACHE_DEEPL_API_KEY = key; CACHE_DEEPL_API_KEY_IS_LOADED = true; } } #endregion #region DeepL Action private static SettingDeepLAction CACHE_DEEPL_ACTION = SettingDeepLAction.MANUAL; private static bool CACHE_DEEPL_ACTION_IS_LOADED = false; public static async Task SetDeepLAction(SettingDeepLAction action) { // Convert the enum to its int value: var intValue = (int)action; // Update the cache: CACHE_DEEPL_ACTION = action; CACHE_DEEPL_ACTION_IS_LOADED = true; // Get the database: await using var db = ProcessorMeta.ServiceProvider.GetRequiredService(); // Check, if the setting is already set: if (await db.Settings.FirstOrDefaultAsync(n => n.Code == SettingNames.DEEPL_ACTION) is {} existingSetting) { existingSetting.IntegerValue = intValue; await db.SaveChangesAsync(); } // Does not exist, so create it: else { var setting = new Setting { Code = SettingNames.DEEPL_ACTION, IntegerValue = intValue, }; await db.Settings.AddAsync(setting); await db.SaveChangesAsync(); } } public static async Task GetDeepLAction() { // Check the cache: if (CACHE_DEEPL_ACTION_IS_LOADED) return CACHE_DEEPL_ACTION; var action = SettingDeepLAction.MANUAL; try { // Get the database: await using var db = ProcessorMeta.ServiceProvider.GetRequiredService(); // Check, if the setting is already set: if (await db.Settings.FirstOrDefaultAsync(n => n.Code == SettingNames.DEEPL_ACTION) is { } existingSetting) { action = (SettingDeepLAction) existingSetting.IntegerValue; return action; } // Does not exist, so create it: var setting = new Setting { Code = SettingNames.DEEPL_ACTION, IntegerValue = (int) action, }; await db.Settings.AddAsync(setting); await db.SaveChangesAsync(); return action; } finally { CACHE_DEEPL_ACTION = action; CACHE_DEEPL_ACTION_IS_LOADED = true; } } #endregion #region DeepL Source Culture private static int CACHE_DEEPL_SOURCE_CULTURE = -1; private static bool CACHE_DEEPL_SOURCE_CULTURE_IS_LOADED = false; public static async Task SetDeepLSourceCultureIndex(int cultureIndex) { // Update the cache: CACHE_DEEPL_SOURCE_CULTURE = cultureIndex; CACHE_DEEPL_SOURCE_CULTURE_IS_LOADED = true; // Get the database: await using var db = ProcessorMeta.ServiceProvider.GetRequiredService(); // Check, if the setting is already set: if (await db.Settings.FirstOrDefaultAsync(n => n.Code == SettingNames.DEEPL_SOURCE_CULTURE) is {} existingSetting) { existingSetting.IntegerValue = cultureIndex; await db.SaveChangesAsync(); } // Does not exist, so create it: else { var setting = new Setting { Code = SettingNames.DEEPL_SOURCE_CULTURE, IntegerValue = cultureIndex, }; await db.Settings.AddAsync(setting); await db.SaveChangesAsync(); } } public static async Task GetDeepLSourceCultureIndex() { // Check the cache: if (CACHE_DEEPL_SOURCE_CULTURE_IS_LOADED) return CACHE_DEEPL_SOURCE_CULTURE; var cultureIndex = -1; try { // Get the database: await using var db = ProcessorMeta.ServiceProvider.GetRequiredService(); // Check, if the setting is already set: if (await db.Settings.FirstOrDefaultAsync(n => n.Code == SettingNames.DEEPL_SOURCE_CULTURE) is { } existingSetting) { cultureIndex = existingSetting.IntegerValue; return cultureIndex; } // Does not exist, so create it: var setting = new Setting { Code = SettingNames.DEEPL_SOURCE_CULTURE, IntegerValue = cultureIndex, }; await db.Settings.AddAsync(setting); await db.SaveChangesAsync(); return cultureIndex; } finally { CACHE_DEEPL_SOURCE_CULTURE = cultureIndex; CACHE_DEEPL_SOURCE_CULTURE_IS_LOADED = true; } } #endregion #endregion #region Translation Settings #region List of culture indices private static List CACHE_CULTURES_INDICES = new(); public static async Task> GetCultureIndices() { // When possible, use the cache: if (CACHE_CULTURES_INDICES.Count > 0) return CACHE_CULTURES_INDICES; // Get the database: await using var db = ProcessorMeta.ServiceProvider.GetRequiredService(); // Count the number of cultures: var list = await db.Settings.Where(n => n.Code.StartsWith(SettingNames.CULTURE)).OrderBy(n => n.IntegerValue).Select(n => n.IntegerValue).ToListAsync(); // We have at least one default culture: if(list.Count == 0) { // Add the default culture, which is en-US: await AppSettings.SetCultureCode(1, "en-US"); } else CACHE_CULTURES_INDICES = list; return CACHE_CULTURES_INDICES; } #endregion #region Get a culture // Cache the cultures: private static readonly Dictionary CACHE_CULTURES = new(); public static async Task GetCultureCode(int index) { // Check the cache: if (CACHE_CULTURES.TryGetValue(index, out var cultureCode)) return cultureCode; // Get the database: await using var db = ProcessorMeta.ServiceProvider.GetRequiredService(); // Get the culture code: var code = await db.Settings.FirstOrDefaultAsync(n => n.Code.StartsWith(SettingNames.CULTURE) && n.IntegerValue == index); // When the culture code is not set & index = 1, use the default culture en-US: if(code is null && index == 1) { CACHE_CULTURES.Add(index, "en-US"); return "en-US"; } // Update the cache & return the code: var codeText = code?.TextValue ?? string.Empty; CACHE_CULTURES[index] = codeText; return codeText; } #endregion #region Set a culture public static async Task SetCultureCode(int index, string code) { // Update the cache: CACHE_CULTURES[index] = code; // Get the database: await using var db = ProcessorMeta.ServiceProvider.GetRequiredService(); // Check, if the setting is already set: if (await db.Settings.FirstOrDefaultAsync(n => n.Code.StartsWith(SettingNames.CULTURE) && n.IntegerValue == index) is {} existingSetting) { existingSetting.TextValue = code; await db.SaveChangesAsync(); } // Does not exist, so create it: else { var setting = new Setting { Code = $"{SettingNames.CULTURE} {index}", IntegerValue = index, TextValue = code, }; await db.Settings.AddAsync(setting); await db.SaveChangesAsync(); // Update the list of cultures indices: CACHE_CULTURES_INDICES.Add(index); } } #endregion #region Delete a culture public static async Task DeleteCulture(int index) { // Get the database: await using var db = ProcessorMeta.ServiceProvider.GetRequiredService(); // Check, if the setting is already set: if (await db.Settings.FirstOrDefaultAsync(n => n.Code.StartsWith(SettingNames.CULTURE) && n.IntegerValue == index) is {} existingSetting) { db.Settings.Remove(existingSetting); await db.SaveChangesAsync(); } // Update the list of cultures indices: CACHE_CULTURES_INDICES.Remove(index); // Update the cache: CACHE_CULTURES.Remove(index); } #endregion #region Get a list of cultures public readonly record struct CultureInfo(string Code, int Index); public static async Task> GetCultureInfos() { // Get the number of cultures: var cultureIndices = await AppSettings.GetCultureIndices(); // Get the culture codes: var cultureInfos = new List(); foreach (var cultureIndex in cultureIndices) cultureInfos.Add(new CultureInfo { Code = await AppSettings.GetCultureCode(cultureIndex), Index = cultureIndex, }); return cultureInfos; } #endregion #endregion }