chaosbot/ChaosBot/ConfigHelpers/Configuration.cs

164 lines
6.4 KiB
C#

using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
namespace ChaosBot.ConfigHelpers
{
public class Configuration
{
private readonly IConfiguration _appSettingsWrapper;
private static readonly Dictionary<string, IConfigurationDetails> ConfigurationFlags = new Dictionary<string, IConfigurationDetails>
{
{"Bot:Name", new ConfigurationDetails<string>("Bot:Name", "ChaosBot", true)},
{"Bot:Version", new ConfigurationDetails<string>("Bot:Version", "1.0.0", true)},
{"WebServer:Port", new ConfigurationDetails<int>("WebServer:Port", 8080, true)},
{"WebServer:Debug", new ConfigurationDetails<bool>("WebServer:Debug", false, true)},
{"Discord:Prefix", new ConfigurationDetails<string>("Discord:Prefix", "!", true)},
{"Discord:Token", new ConfigurationDetails<string>("Discord:Token", "SECRET_TOKEN", true)},
{"Discord:BaseUri", new ConfigurationDetails<string>("Discord:BaseUri", "http://localhost:8080/", true)},
{"Discord:ClientId", new ConfigurationDetails<string>("Discord:ClientId", "1234567890", true)},
{"Discord:ClientSecret", new ConfigurationDetails<string>("Discord:ClientSecret", "1234567890_SECRET_TOKEN", true)},
{"Lodestone:ChaosBotApi:ApiToken", new ConfigurationDetails<string>("Lodestone:ChaosBotApi:ApiToken", "SECRET_TOKEN", true)},
{"Lodestone:ChaosBotApi:Url", new ConfigurationDetails<string>("Lodestone:ChaosBotApi:Url", "http://locahost:8000", true)},
{"Database:Host", new ConfigurationDetails<string>("Database:Host", "localhost", true)},
{"Database:Port", new ConfigurationDetails<int>("Database:Port", 3306, true)},
{"Database:User", new ConfigurationDetails<string>("Database:User", "root", true)},
{"Database:Pass", new ConfigurationDetails<string>("Database:Pass", "password", true)},
{"Database:Name", new ConfigurationDetails<string>("Database:Name", "chaosbot", true)},
{"Module:Experience:Enabled", new ConfigurationDetails<bool>("Module:Experience:Enabled", true, false)},
{"LevelUp:Channel", new ConfigurationDetails<string>("LevelUp:Channel", null, false)},
{"LevelUp:MentionUser", new ConfigurationDetails<bool>("LevelUp:MentionUser", true, false)},
};
public Configuration()
{
_appSettingsWrapper = GetAppSettingsWrapper();
}
public IConfigurationDetails GetByKey(string key)
{
if (ConfigurationFlags.TryGetValue(key, out IConfigurationDetails details))
{
return details;
}
throw new ArgumentException($"Configuration '{key}' is not available");
}
public IConfigurationDetails<T> GetByKey<T>(string key)
{
IConfigurationDetails configurationDetails = GetByKey(key);
if (configurationDetails.Type != typeof(T))
throw new ArgumentException($"Configuration flag '{key}' is not of type '{typeof(T)}'");
return (IConfigurationDetails<T>) configurationDetails;
}
internal static IConfiguration GetAppSettingsWrapper()
{
if (Program.AppSettingsHandler == null)
throw new NullReferenceException("Program.AppSettingsHandler is unset");
return Program.AppSettingsHandler;
}
public ImmutableDictionary<string, IConfigurationDetails> GetConfigurationFlags()
{
return ConfigurationFlags.ToImmutableDictionary();
}
public IConfigurationSection GetSection(string key)
{
return _appSettingsWrapper.GetSection(key);
}
}
public interface IConfigurationDetails
{
string Key { get; }
bool Restricted { get; }
Type Type { get; }
object DefaultValue { get; }
string GetStringValue(ulong guildId);
void SetValueFromString(string value, ulong guildId);
void DeleteValue(ulong guildId);
}
public interface IConfigurationDetails<T> : IConfigurationDetails
{
new T DefaultValue { get; }
T GetValue(ulong? guildId = null, bool readRestricted = false);
T GetValue(T defaultValue, ulong? guildId = null, bool readRestricted = false);
void SetValue(T value, ulong guildId);
}
public class ConfigurationDetails<T> : IConfigurationDetails<T>
{
public string Key { get; }
public bool Restricted { get; }
public T DefaultValue { get; }
object IConfigurationDetails.DefaultValue => DefaultValue;
public Type Type => typeof(T);
public ConfigurationDetails(string key, T defaultValue, bool restricted)
{
Key = key;
DefaultValue = defaultValue;
Restricted = restricted;
}
public T GetValue(ulong? guildId = null, bool readRestricted = false)
{
return GetValue(DefaultValue, guildId, readRestricted);
}
public T GetValue(T defaultValue, ulong? guildId = null, bool readRestricted = false)
{
if (!readRestricted && Restricted)
throw new UnauthorizedAccessException($"Configuration key '{Key}' is restricted");
if (guildId.HasValue)
{
return ConfigurationRepository.GetValue(Key, guildId.Value, defaultValue);
}
return Configuration.GetAppSettingsWrapper().GetValue(Key, defaultValue);
}
public string GetStringValue(ulong guildId)
{
return GetValue(guildId: guildId).ToString();
}
public void SetValue(T value, ulong guildId)
{
if (Restricted)
throw new UnauthorizedAccessException($"Configuration key '{Key}' is restricted");
ConfigurationRepository.SetValue(Key, value, guildId);
}
public void SetValueFromString(string value, ulong guildId)
{
SetValue((T)Convert.ChangeType(value, typeof(T)), guildId);
}
public void DeleteValue(ulong guildId)
{
if (Restricted)
throw new UnauthorizedAccessException($"Configuration key '{Key}' is restricted");
ConfigurationRepository.DeleteValue(Key, guildId);
}
}
}