using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Text.RegularExpressions; using Microsoft.Extensions.Configuration; namespace ChaosBot.ConfigHelpers { public class Configuration { private readonly IConfiguration _appSettingsWrapper; private static readonly Dictionary ConfigurationFlags = new Dictionary { {"Bot:Name", (typeof(string), "ChaosBot")}, {"Bot:Version", (typeof(string), "1.0.0")}, {"WebServer:Port", (typeof(int), 8080)}, {"WebServer:Debug", (typeof(bool), false)}, {"Discord:Prefix", (typeof(string), "!")}, {"Discord:Token", (typeof(string), "SECRET_TOKEN")}, {"Discord:BaseUri", (typeof(string), "http://localhost:8080/")}, {"Discord:ClientId", (typeof(string), "1234567890")}, {"Discord:ClientSecret", (typeof(string), "1234567890_SECRET_TOKEN")}, {"Lodestone:ChaosBotApi:ApiToken", (typeof(string), "SECRET_TOKEN")}, {"Lodestone:ChaosBotApi:Url", (typeof(string), "http://locahost:8000")}, {"Database:Host", (typeof(string), "localhost")}, {"Database:Port", (typeof(int), 3306)}, {"Database:User", (typeof(string), "root")}, {"Database:Pass", (typeof(string), "password")}, {"Database:Name", (typeof(string), "chaosbot")}, {"Module:Experience:Enabled", (typeof(bool), true)}, {"LevelUp:Channel", (typeof(string), null)}, {"LevelUp:MentionUser", (typeof(bool), true)}, }; public Configuration() { _appSettingsWrapper = Program.AppSettingsHandler; if (_appSettingsWrapper == null) throw new NullReferenceException("Program.AppSettingsHandler is unset"); } /** * Gets the configuration value associated with a key in an optional guild * Configuration key does not exist * Configuration key does not have the provided type * Configuration value */ public T GetValue(string key, T defaultValue, ulong? guildId = null) { string realKey = EnsureKeyExistsAndTypeCorrect(key); if (guildId.HasValue) return ConfigurationRepository.GetValue(realKey, guildId.Value, defaultValue); return _appSettingsWrapper.GetValue(realKey, defaultValue); } public T GetValue(string key) { return GetValue(key, default); } public T GetValueGlobalDefault(string key, ulong? guildId = null) { bool keyExists = TryGetKeyFromRegexMatch(key, out string realKey); object defaultObject = keyExists ? ConfigurationFlags[realKey].defaultValue : null; T defaultValue = default; if (defaultObject != null) defaultValue = (T)Convert.ChangeType(defaultObject, typeof(T)); return GetValue(key, defaultValue); } public IConfigurationSection GetSection(string key) { return _appSettingsWrapper.GetSection(key); } public void DeleteValue(string key, ulong guildId) { ConfigurationRepository.DeleteValue(key, guildId); } /** * Get the available configuration flags * Immutable dictionary of config-key/type pairs */ public ImmutableDictionary GetConfigurationFlags() { return ConfigurationFlags.ToImmutableDictionary(); } private string EnsureKeyExistsAndTypeCorrect(string key) { bool keyExists = TryGetKeyFromRegexMatch(key, out string realKey); if (!keyExists) throw new ArgumentException($"Configuration does not contain key '{key}'"); if (!(ConfigurationFlags[realKey].type == typeof(T))) throw new ArgumentException( $"Configuration flag '{realKey}<{ConfigurationFlags[realKey]}>' does not have type '{typeof(T)}'"); return realKey; } private bool TryGetKeyFromRegexMatch(string key, out string realKey) { if (ConfigurationFlags.ContainsKey(key)) { realKey = key; return true; } foreach (string configurationFlagsKey in ConfigurationFlags.Keys) { if (new Regex(configurationFlagsKey).IsMatch(key)) { realKey = key; return true; } } realKey = null; return false; } } }