using System.CommandLine; using System.CommandLine.Parsing; using ScadaLink.Commons.Messages.Management; namespace ScadaLink.CLI.Commands; public static class NotificationCommands { public static Command Build(Option urlOption, Option formatOption, Option usernameOption, Option passwordOption) { var command = new Command("notification") { Description = "Manage notification lists" }; command.Add(BuildList(urlOption, formatOption, usernameOption, passwordOption)); command.Add(BuildGet(urlOption, formatOption, usernameOption, passwordOption)); command.Add(BuildCreate(urlOption, formatOption, usernameOption, passwordOption)); command.Add(BuildUpdate(urlOption, formatOption, usernameOption, passwordOption)); command.Add(BuildDelete(urlOption, formatOption, usernameOption, passwordOption)); command.Add(BuildSmtp(urlOption, formatOption, usernameOption, passwordOption)); return command; } private static Command BuildGet(Option urlOption, Option formatOption, Option usernameOption, Option passwordOption) { var idOption = new Option("--id") { Description = "Notification list ID", Required = true }; var cmd = new Command("get") { Description = "Get a notification list by ID" }; cmd.Add(idOption); cmd.SetAction(async (ParseResult result) => { var id = result.GetValue(idOption); return await CommandHelpers.ExecuteCommandAsync( result, urlOption, formatOption, usernameOption, passwordOption, new GetNotificationListCommand(id)); }); return cmd; } private static Command BuildUpdate(Option urlOption, Option formatOption, Option usernameOption, Option passwordOption) { var idOption = new Option("--id") { Description = "Notification list ID", Required = true }; var nameOption = new Option("--name") { Description = "List name", Required = true }; var emailsOption = new Option("--emails") { Description = "Comma-separated recipient emails", Required = true }; var cmd = new Command("update") { Description = "Update a notification list" }; cmd.Add(idOption); cmd.Add(nameOption); cmd.Add(emailsOption); cmd.SetAction(async (ParseResult result) => { var id = result.GetValue(idOption); var name = result.GetValue(nameOption)!; var emailsRaw = result.GetValue(emailsOption)!; var emails = emailsRaw.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries).ToList(); return await CommandHelpers.ExecuteCommandAsync( result, urlOption, formatOption, usernameOption, passwordOption, new UpdateNotificationListCommand(id, name, emails)); }); return cmd; } private static Command BuildSmtp(Option urlOption, Option formatOption, Option usernameOption, Option passwordOption) { var group = new Command("smtp") { Description = "Manage SMTP configuration" }; var listCmd = new Command("list") { Description = "List SMTP configurations" }; listCmd.SetAction(async (ParseResult result) => { return await CommandHelpers.ExecuteCommandAsync( result, urlOption, formatOption, usernameOption, passwordOption, new ListSmtpConfigsCommand()); }); group.Add(listCmd); var updateCmd = new Command("update") { Description = "Update SMTP configuration" }; updateCmd.Add(SmtpIdOption); updateCmd.Add(SmtpServerOption); updateCmd.Add(SmtpPortOption); updateCmd.Add(SmtpAuthModeOption); updateCmd.Add(SmtpFromOption); updateCmd.Add(SmtpTlsModeOption); updateCmd.Add(SmtpCredentialsOption); updateCmd.SetAction(async (ParseResult result) => { return await CommandHelpers.ExecuteCommandAsync( result, urlOption, formatOption, usernameOption, passwordOption, BuildUpdateSmtpConfigCommand(result)); }); group.Add(updateCmd); return group; } // SMTP update options are static so the parsed values can be read back both // from the SetAction and from BuildUpdateSmtpConfigCommand (used by tests). private static readonly Option SmtpIdOption = new("--id") { Description = "SMTP config ID", Required = true }; private static readonly Option SmtpServerOption = new("--server") { Description = "SMTP server", Required = true }; private static readonly Option SmtpPortOption = new("--port") { Description = "SMTP port", Required = true }; private static readonly Option SmtpAuthModeOption = new("--auth-mode") { Description = "Auth mode", Required = true }; private static readonly Option SmtpFromOption = new("--from-address") { Description = "From email address", Required = true }; private static readonly Option SmtpTlsModeOption = CreateTlsModeOption(); private static readonly Option SmtpCredentialsOption = new("--credentials") { Description = "SMTP credentials — 'username:password' for Basic, or client secret " + "for OAuth2 (optional; preserves existing if omitted)", }; private static Option CreateTlsModeOption() { var option = new Option("--tls-mode") { Description = "TLS mode: None, StartTLS, or SSL (optional; preserves existing if omitted)", }; option.AcceptOnlyFromAmong("None", "StartTLS", "SSL"); return option; } /// /// Builds the from a parsed smtp update /// invocation. The optional --tls-mode / --credentials flags map to /// null when omitted so the server-side handler preserves the existing values. /// internal static UpdateSmtpConfigCommand BuildUpdateSmtpConfigCommand(ParseResult result) { var id = result.GetValue(SmtpIdOption); var server = result.GetValue(SmtpServerOption)!; var port = result.GetValue(SmtpPortOption); var authMode = result.GetValue(SmtpAuthModeOption)!; var from = result.GetValue(SmtpFromOption)!; var tlsMode = result.GetValue(SmtpTlsModeOption); var credentials = result.GetValue(SmtpCredentialsOption); return new UpdateSmtpConfigCommand(id, server, port, authMode, from, tlsMode, credentials); } private static Command BuildList(Option urlOption, Option formatOption, Option usernameOption, Option passwordOption) { var cmd = new Command("list") { Description = "List all notification lists" }; cmd.SetAction(async (ParseResult result) => { return await CommandHelpers.ExecuteCommandAsync( result, urlOption, formatOption, usernameOption, passwordOption, new ListNotificationListsCommand()); }); return cmd; } private static Command BuildCreate(Option urlOption, Option formatOption, Option usernameOption, Option passwordOption) { var nameOption = new Option("--name") { Description = "Notification list name", Required = true }; var emailsOption = new Option("--emails") { Description = "Comma-separated recipient emails", Required = true }; var cmd = new Command("create") { Description = "Create a notification list" }; cmd.Add(nameOption); cmd.Add(emailsOption); cmd.SetAction(async (ParseResult result) => { var name = result.GetValue(nameOption)!; var emailsRaw = result.GetValue(emailsOption)!; var emails = emailsRaw.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries).ToList(); return await CommandHelpers.ExecuteCommandAsync( result, urlOption, formatOption, usernameOption, passwordOption, new CreateNotificationListCommand(name, emails)); }); return cmd; } private static Command BuildDelete(Option urlOption, Option formatOption, Option usernameOption, Option passwordOption) { var idOption = new Option("--id") { Description = "Notification list ID", Required = true }; var cmd = new Command("delete") { Description = "Delete a notification list" }; cmd.Add(idOption); cmd.SetAction(async (ParseResult result) => { var id = result.GetValue(idOption); return await CommandHelpers.ExecuteCommandAsync( result, urlOption, formatOption, usernameOption, passwordOption, new DeleteNotificationListCommand(id)); }); return cmd; } }