using HanaTui.Hana; using Spectre.Console; using SysText = System.Text; namespace HanaTui.Tui; /// /// Startup screen: lists hdbuserstore keys and lets the user pick one. /// Returns the selected key name, or null if the user chose to exit. /// public static class KeySelectionScreen { private sealed class KeyChoice { public string Display { get; init; } = ""; public string? KeyName { get; init; } // null = exit, "" = manual entry public static readonly KeyChoice Manual = new() { Display = "[ Enter key name manually ]", KeyName = "" }; public static readonly KeyChoice Exit = new() { Display = "[ Exit ]", KeyName = null }; public override string ToString() => Display; } public static string? Run() { AnsiConsole.Clear(); AnsiConsole.Write(new FigletText("HANA TUI").Color(Color.DodgerBlue1)); AnsiConsole.MarkupLine("[dim]SAP HANA Database Manager[/]\n"); if (!HdbClientLocator.IsAvailable()) { AnsiConsole.MarkupLine("[red][[ERROR]][/] hdbsql not found. " + "Ensure the SAP HANA client is installed and on your PATH, " + "or present in [dim]/usr/sap/hdbclient[/] or [dim]/usr/sap/NDB/HDB00/exe[/]."); AnsiConsole.MarkupLine("\nPress any key to exit."); Console.ReadKey(intercept: true); return null; } var clientDir = HdbClientLocator.ClientDirectory; if (clientDir is not null) AnsiConsole.MarkupLine($"[dim]HDB client: {Markup.Escape(clientDir)}[/]\n"); List keys = []; AnsiConsole.Status() .Spinner(Spinner.Known.Dots) .SpinnerStyle(Style.Parse("blue")) .Start("[blue]Loading hdbuserstore keys...[/]", _ => { keys = HdbCliRunner.ListKeys(); }); if (keys.Count == 0) { AnsiConsole.MarkupLine("[yellow][[WARN]][/] No hdbuserstore keys found."); AnsiConsole.MarkupLine("You can still enter a key name manually.\n"); } // Build typed choices. Display is plain text — never parsed as markup. var choices = keys .Select(k => new KeyChoice { Display = BuildKeyDisplay(k), KeyName = k.Name }) .ToList(); choices.Add(KeyChoice.Manual); choices.Add(KeyChoice.Exit); var prompt = new SelectionPrompt() .Title("[bold]Select HDBUSERSTORE key:[/]") .PageSize(15) .HighlightStyle(Style.Parse("bold dodgerblue1")) .UseConverter(c => Markup.Escape(c.Display)) .AddChoices(choices); var selected = AnsiConsole.Prompt(prompt); if (selected.KeyName is null) return null; // Exit if (selected.KeyName == "") { var manual = AnsiConsole.Ask("[bold]Enter HDBUSERSTORE key name:[/]").Trim(); return string.IsNullOrWhiteSpace(manual) ? null : manual; } return selected.KeyName; } private static string BuildKeyDisplay(HdbUserstoreKey k) { var sb = new SysText.StringBuilder(k.Name); if (!string.IsNullOrEmpty(k.Host)) { sb.Append(" "); sb.Append(k.Host); if (!string.IsNullOrEmpty(k.Port)) { sb.Append(':'); sb.Append(k.Port); } if (!string.IsNullOrEmpty(k.Tenant)) { sb.Append('@'); sb.Append(k.Tenant); } } if (!string.IsNullOrEmpty(k.User)) { sb.Append(" user="); sb.Append(k.User); } return sb.ToString(); } }