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();
}
}