using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; using InABox.Core; namespace InABox.Configuration { public interface ILocalConfigurationSettings : IConfigurationSettings { } public class LocalConfiguration : Configuration, IDisposable where T : ILocalConfigurationSettings, new() { public LocalConfiguration(string section = "") : base(section) { Folder = GetPath(); } public LocalConfiguration(string folder, string section) : base(section) { Folder = folder; } public string Folder { get; set; } private string GetPath() => CoreUtils.GetPath(); public string GetFileName() { return Path.Combine( Folder, typeof(T).Name + ".settings" ); } private string EnsureFileName() { if (!Directory.Exists(Folder)) Directory.CreateDirectory(Folder); return GetFileName(); } protected virtual string SerializeConfiguration(Dictionary config) { return Serialization.Serialize(config, true); } protected virtual Dictionary? DeserializeConfiguration(string text) { return Serialization.Deserialize>(text); } private Dictionary LoadCurrentConfig(string filename) { Dictionary? config = null; if (File.Exists(filename)) config = DeserializeConfiguration(File.ReadAllText(filename)); return config ?? new Dictionary(); } public override T Load(bool useCache = true) { if (useCache) { var cached = ConfigurationCache.Check(ConfigurationCacheType.Local, Section); if (cached != null) //Logger.Send(LogType.Information, "", "Local Config: Returning Cached Configuration Data"); return cached; } //Logger.Send(LogType.Information, "", "Local Config: Creating "+typeof(T).EntityName().Split('.').Last()); var result = new T(); var filename = EnsureFileName(); //Logger.Send(LogType.Information, "", "Local Config: FileName is ["+filename+"]"); if (File.Exists(filename)) { //Logger.Send(LogType.Information, "", "Local Config: Deserializing Configuration"); var config = DeserializeConfiguration(File.ReadAllText(filename)); //Toml.ReadString(File.ReadAllText(FileName)); if (config != null && config.ContainsKey(Section)) //Logger.Send(LogType.Information, "", "Local Config: Found Section ["+Section+"}"); if (config[Section] != null) //Logger.Send(LogType.Information, "", "Local Config: ["+Section+"] is not null"); result = config[Section]; } //Logger.Send(LogType.Information, "", "Local Config: Adding Configuration to Cache"); ConfigurationCache.Add(ConfigurationCacheType.Local, Section, result); return result; } public override Dictionary LoadAll(IEnumerable? sections = null) { var config = LoadCurrentConfig(EnsureFileName()); return sections != null ? sections.ToDictionary(x => x, x => config.GetValueOrDefault(x)) : config; } public override void Save(T obj) { var filename = EnsureFileName(); var config = LoadCurrentConfig(filename); config[Section] = obj; var contents = SerializeConfiguration(config); File.WriteAllText(filename, contents); ConfigurationCache.Add(ConfigurationCacheType.Local, Section, obj); } public override void SaveAll(Dictionary objs, bool reset = false) { var filename = EnsureFileName(); var config = reset ? new Dictionary() : LoadCurrentConfig(filename); foreach(var (section, obj) in objs) { config[section] = obj; } var contents = SerializeConfiguration(config); File.WriteAllText(filename, contents); foreach(var (section, obj) in objs) { ConfigurationCache.Add(ConfigurationCacheType.Local, section, obj); } } public override void Delete(Action? callback = null) { var filename = EnsureFileName(); var config = LoadCurrentConfig(filename); if (config.ContainsKey(Section)) config.Remove(Section); if (config.Any()) { var contents = SerializeConfiguration(config); File.WriteAllText(filename, contents); } else { if (File.Exists(filename)) File.Delete(filename); } ConfigurationCache.Clear(ConfigurationCacheType.Local, Section); callback?.Invoke(null); } public override string[] Sections() { if (!Directory.Exists(Folder)) return new[] { "" }; var filename = GetFileName(); if (!File.Exists(filename)) return new[] { "" }; var config = DeserializeConfiguration(File.ReadAllText(filename)); if (config == null) return new[] { "" }; return config.Keys.ToArray(); } public void Dispose() { } } public class EncryptedLocalConfiguration : LocalConfiguration where T : ILocalConfigurationSettings, new() { private byte[] Key; public EncryptedLocalConfiguration(byte[] key, string section = "") : base(section) { Key = key; } public EncryptedLocalConfiguration(byte[] key, string section, string folder) : base(section, folder) { Key = key; } public EncryptedLocalConfiguration(string key, string section = "") : this(ConvertKey(key), section) { } public EncryptedLocalConfiguration(string key, string section, string folder) : this(ConvertKey(key), section, folder) { } protected override string SerializeConfiguration(Dictionary config) { return Encryption.EncryptV2(base.SerializeConfiguration(config), Key); } protected override Dictionary? DeserializeConfiguration(string text) { return base.DeserializeConfiguration(Encryption.DecryptV2(text, Key)); } private static byte[] ConvertKey(string key) { return Convert.FromBase64String(key); } } }