using System; using System.Collections.Generic; using System.IO; using Avalonia.Media; using Cogwheel; namespace SessionZero; public class AppSettings { public string SettingsFilePath { get; set; } = ""; public Dictionary Settings { get; set; } = new(); public AppSetting CreateSetting(string settingName, Type settingType) { return new AppSetting(settingName, settingType); } public void AddSetting(AppSetting setting) { if (!Settings.TryAdd(setting.SettingName, setting)) { COGWHEEL.LogError($"Cannot add setting: '{setting.SettingName}'. Setting already exists."); } } public AppSetting? GetSetting(string settingName) { if (!Settings.TryGetValue(settingName, out var setting)) { COGWHEEL.LogError($"Cannot get setting: '{settingName}'. Setting does not exist."); return null; } return setting; } public void RemoveSetting(string settingName) { if (!Settings.Remove(settingName)) { COGWHEEL.LogError($"Cannot remove setting: '{settingName}. It may not exist."); } } public bool SetSettingValue(string settingName, T value) { if (Settings.TryGetValue(settingName, out var setting)) { return setting.SetValue(value); } COGWHEEL.LogError($"Cannot set setting: '{settingName}'. Setting does not exist."); return false; } public bool SetSettingValue(string settingName, string value) { if (Settings.TryGetValue(settingName, out var setting)) { return setting.SetValue(value); } COGWHEEL.LogError($"Cannot set setting: '{settingName}'. Setting does not exist."); return false; } public T? GetValue(string settingName) { if (Settings.TryGetValue(settingName, out var setting)) { return setting.GetValue(); } return default; } public string GetValueAsString(string settingName) { if (!Settings.TryGetValue(settingName, out var setting) || setting == null) { COGWHEEL.LogError($"Cannot get setting '{settingName}'. Setting does not exist."); return string.Empty; } var type = setting.SettingType; try { var method = typeof(AppSetting).GetMethod(nameof(AppSetting.GetValue))!; var generic = method.MakeGenericMethod(type); var valueObj = generic.Invoke(setting, null); if (valueObj == null) return string.Empty; if (type == typeof(string)) return (string)valueObj; if (type.IsPrimitive || type.IsEnum || type == typeof(decimal)) return Convert.ToString(valueObj) ?? string.Empty; return valueObj.ToString() ?? string.Empty; } catch (Exception ex) { COGWHEEL.LogError($"Failed to get setting '{settingName}' as string: {ex.Message}"); return string.Empty; } } public void SaveToFile() {} public void LoadFromFile() {} } public class AppSetting(string settingName, Type settingType) { public string SettingName { get; } = settingName; public Type SettingType { get; } = settingType; private object? _settingValue; public T GetValue() { if (typeof(T) != SettingType) { COGWHEEL.LogError($"Cannot get value of setting '{SettingName}': Setting is type '{SettingType.Name}' but GetValue was called with type '{typeof(T).Name}'.'"); } return _settingValue is null ? default! : (T)_settingValue; } public bool SetValue(T value) { if (typeof(T) != SettingType) { COGWHEEL.LogError($"Cannot set value of setting '{SettingName}': Setting is type '{SettingType.Name}' but SetValue was called with type '{typeof(T).Name}'.'"); return false; } _settingValue = value!; return true; } public bool SetValue(object? value) { if (value == null) { _settingValue = null; return true; } if (SettingType.IsInstanceOfType(value)) { _settingValue = value; return true; } try { var converted = Convert.ChangeType(value, SettingType); _settingValue = converted; return true; } catch { COGWHEEL.LogError($"Cannot convert value '{value}' to {SettingType.Name} for setting '{SettingName}'."); return false; } } public bool SetValue(string valueString) { try { object? parsedValue = null; if (SettingType == typeof(string)) { parsedValue = valueString; } else if (SettingType == typeof(int)) { if (!int.TryParse(valueString, out var i)) { COGWHEEL.LogError($"Cannot parse '{valueString}' as int for setting '{SettingName}'."); return false; } parsedValue = i; } else if (SettingType == typeof(float)) { if (!float.TryParse(valueString, out var f)) { COGWHEEL.LogError($"Cannot parse '{valueString}' as float for setting '{SettingName}'."); return false; } parsedValue = f; } else if (SettingType == typeof(bool)) { if (!bool.TryParse(valueString, out var b)) { COGWHEEL.LogError($"Cannot parse '{valueString}' as bool for setting '{SettingName}'."); return false; } parsedValue = b; } else { COGWHEEL.LogError( $"Unsupported setting type '{SettingType.Name}' in SetValue(string) for setting '{SettingName}'."); return false; } _settingValue = parsedValue; return true; } catch (Exception ex) { COGWHEEL.LogError($"Failed to set setting '{SettingName}' to '{valueString}': {ex.Message}"); return false; } } } static class AppSettingsCommands { [Command(Name = "setsetting")] public static void SetSetting(string settingName, string value) { if (AppManager.Settings.SetSettingValue(settingName, value)) { COGWHEEL.Log($"Setting '{settingName}' set to '{value}'."); } } [Command(Name = "getsetting")] public static void GetSetting(string settingName) { var value = AppManager.Settings.GetValueAsString(settingName); COGWHEEL.Log($"Setting '{settingName}' value is: ({AppManager.Settings.GetSetting(settingName)?.SettingType.Name}){value}."); } [Command(Name = "listsettings")] public static void ListSettings(string settingName = "") { var outputString = $"-- Settings --\n"; if (string.IsNullOrEmpty(settingName)) { foreach (var setting in AppManager.Settings.Settings) { outputString += $"{setting.Value.SettingName}: {setting.Value.SettingType.Name} = {AppManager.Settings.GetValueAsString(setting.Key)}\n"; } AppManager.ConsoleControl.Log(outputString, Colors.CadetBlue); } else { COGWHEEL.LogWarning($"Searching for settings is not implemented yet."); } } // TODO: Go update Cogwheel to accept array arguments somehow // [Command(Name = "setting")] // public static void SettingCommand(string[] args) // { // if (args.Length == 0) // { // COGWHEEL.LogError("No arguments supplied. Usage: 'setting '"); // } // // var action = args[0]; // List actionArgs = new(); // for (int i = 1; i < args.Length; i++) // { // actionArgs.Add(args[i]); // } // // switch (action) // { // case "set": // if (actionArgs.Count == 2) // { // var settingName = args[0]; // var settingValue = args[1]; // // if (AppManager.Settings.SetSettingValue(settingName, settingValue)) // { // COGWHEEL.Log($"Setting '{settingName}' successfully set to '{settingValue}'."); // } // } // else // { // COGWHEEL.LogError($"Invalid number of arguments for '{action}'. Usage: 'setting set '"); // } // break; // case "get": // if (actionArgs.Count == 1) // { // var val = AppManager.Settings.GetValueAsString(args[0]); // COGWHEEL.Log($"Value of Setting '{args[0]}' is '{val}'."); // } // else // { // COGWHEEL.LogError($"Invalid number of arguments for '{action}'. Usage: 'setting get '"); // } // break; // case "add": // break; // case "remove": // break; // default: // COGWHEEL.LogError($"Unknown argument '{action}' for 'setting' command. Options are 'set, get, add, remove'."); // break; // } // } }