using System.ComponentModel; using System.Text.Json; namespace Predictalytics.WinFormsHost; public class AppSettings { private const string FileName = "settings.json"; [Category("Webserver")] [DisplayName("Port")] [Description("Der Port, über den die WebUI und API erreichbar sind.")] [DefaultValue(5000)] public int WebserverPort { get; set; } = 5000; [Category("Webserver")] [DisplayName("Database Debug")] [Description("Wenn aktiv, werden detaillierte Verbindungsinformationen im Terminal angezeigt.")] [DefaultValue(false)] public bool DbConnectionDebug { get; set; } = false; private string _egressChannelsText = ""; [Category("Egress (Proxy/IP)")] [DisplayName("Egress Channels")] [Description("Liste der Egress-Kanäle im Format: id|type|value (Zeilengetrennt). Beispiel: prox-1|Proxy|http://user:pass@proxy:8080\nip-1|SourceIp|192.168.1.100")] [Editor("System.ComponentModel.Design.MultilineStringEditor, System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(System.Drawing.Design.UITypeEditor))] public string EgressChannelsText { get => _egressChannelsText; set => _egressChannelsText = value ?? ""; } [Category("Watchdog")] [DisplayName("Enabled")] [Description("Sendet periodische Heartbeats an den externen Watchdog-Server (Dead-Man's-Switch). Benötigt einen API Key.")] [DefaultValue(true)] public bool WatchdogEnabled { get; set; } = true; [Category("Watchdog")] [DisplayName("Server URL")] [Description("Basis-URL des Watchdog-Servers.")] [DefaultValue("https://watchdog.mhdf.de")] public string WatchdogUrl { get; set; } = "https://watchdog.mhdf.de"; [Category("Watchdog")] [DisplayName("API Key")] [Description("Shared Key oder Agent-Token des Watchdog-Servers (X-Watchdog-Key). Ohne Key werden keine Heartbeats gesendet.")] [PasswordPropertyText(true)] public string WatchdogApiKey { get; set; } = ""; [Category("Watchdog")] [DisplayName("Source")] [Description("Eindeutiger Monitor-Name dieses Dienstes im Watchdog-Dashboard.")] [DefaultValue("Predictalytics")] public string WatchdogSource { get; set; } = "Predictalytics"; [Category("Watchdog")] [DisplayName("Instance")] [Description("Instanz-Kennung, falls mehrere Predictalytics-Instanzen laufen.")] [DefaultValue("default")] public string WatchdogInstance { get; set; } = "default"; [Category("Watchdog")] [DisplayName("Interval (Sekunden)")] [Description("Sende-Takt der Heartbeats. Der Watchdog alarmiert, wenn ~1,5× dieses Intervall + 30 s ohne Heartbeat vergehen.")] [DefaultValue(60)] public int WatchdogIntervalSeconds { get; set; } = 60; private string _dbServer = "localhost"; private string _dbName = ""; private string _dbUser = ""; private string _dbPassword = ""; [Category("Database")] [DisplayName("Server")] public string DbServer { get => _dbServer; set => _dbServer = string.IsNullOrWhiteSpace(value) ? _dbServer : value.Trim(); } [Category("Database")] [DisplayName("Database")] public string DbName { get => _dbName; set => _dbName = string.IsNullOrWhiteSpace(value) ? _dbName : value.Trim(); } [Category("Database")] [DisplayName("User")] public string DbUser { get => _dbUser; set => _dbUser = string.IsNullOrWhiteSpace(value) ? _dbUser : value.Trim(); } [Category("Database")] [DisplayName("Password")] [PasswordPropertyText(true)] public string DbPassword { get => _dbPassword; set => _dbPassword = string.IsNullOrWhiteSpace(value) ? _dbPassword : value.Trim(); } [Browsable(false)] public string ConnectionString { get { var builder = new MySqlConnector.MySqlConnectionStringBuilder { Server = DbServer?.Trim(), Database = DbName?.Trim(), UserID = DbUser?.Trim(), Password = DbPassword?.Trim(), AllowPublicKeyRetrieval = true, SslMode = MySqlConnector.MySqlSslMode.None, Pooling = true, MinimumPoolSize = 0, MaximumPoolSize = 100 }; return builder.ConnectionString; } } public static AppSettings Load() { var filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, FileName); if (!File.Exists(filePath)) { var settings = new AppSettings(); settings.Save(); return settings; } try { var json = File.ReadAllText(filePath); return JsonSerializer.Deserialize(json) ?? new AppSettings(); } catch { return new AppSettings(); } } public void Save() { var filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, FileName); var options = new JsonSerializerOptions { WriteIndented = true }; var json = JsonSerializer.Serialize(this, options); File.WriteAllText(filePath, json); } }