chaosbot/ChaosBot/ConfigHelpers/Configuration.cs

137 lines
4.9 KiB
C#

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<string, (Type type, object defaultValue)> ConfigurationFlags = new Dictionary<string, (Type type, object defaultValue)>
{
{"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
* <exception cref="ArgumentException">Configuration key does not exist</exception>
* <exception cref="ArgumentException">Configuration key does not have the provided type</exception>
* <returns>Configuration value</returns>
*/
public T GetValue<T>(string key, T defaultValue, ulong? guildId = null)
{
string realKey = EnsureKeyExistsAndTypeCorrect<T>(key);
if (guildId.HasValue)
return ConfigurationRepository.GetValue(realKey, guildId.Value, defaultValue);
return _appSettingsWrapper.GetValue(realKey, defaultValue);
}
public T GetValue<T>(string key)
{
return GetValue<T>(key, default);
}
public T GetValueGlobalDefault<T>(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
* <returns>Immutable dictionary of config-key/type pairs</returns>
*/
public ImmutableDictionary<string, (Type type, object defaultvalue)> GetConfigurationFlags()
{
return ConfigurationFlags.ToImmutableDictionary();
}
private string EnsureKeyExistsAndTypeCorrect<T>(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;
}
}
}