namespace ZB.MOM.WW.Tools.LdapProbe;
/// Console formatting and credential prompting.
public static class Ui
{
public static void Section(string title)
{
Console.WriteLine();
Write(ConsoleColor.Cyan, $"── {title} " + new string('─', Math.Max(0, 66 - title.Length)));
}
public static void Ok(string message) => Write(ConsoleColor.Green, " ✓ " + message);
public static void Bad(string message) => Write(ConsoleColor.Red, " ✗ " + message);
public static void Warn(string message) => Write(ConsoleColor.Yellow, " ! " + message);
public static void Info(string message) => Console.WriteLine(" " + message);
public static void Field(string name, string? value) =>
Console.WriteLine($" {name,-22} {value ?? "(not set)"}");
private static void Write(ConsoleColor color, string message)
{
var previous = Console.ForegroundColor;
try
{
Console.ForegroundColor = color;
Console.WriteLine(message);
}
finally
{
Console.ForegroundColor = previous;
}
}
public static string Prompt(string label, string? preset = null)
{
if (!string.IsNullOrWhiteSpace(preset)) return preset;
Console.Write($" {label}: ");
return Console.ReadLine()?.Trim() ?? "";
}
///
/// Reads a password without echoing it. Falls back to a plain read when input is
/// redirected (a pipe has no key events), so the probe still works non-interactively.
///
public static string PromptSecret(string label)
{
Console.Write($" {label}: ");
if (Console.IsInputRedirected)
{
var piped = Console.ReadLine() ?? "";
Console.WriteLine("(read from stdin)");
return piped;
}
var buffer = new Stack();
while (true)
{
var key = Console.ReadKey(intercept: true);
switch (key.Key)
{
case ConsoleKey.Enter:
Console.WriteLine();
return new string(buffer.Reverse().ToArray());
case ConsoleKey.Backspace when buffer.Count > 0:
buffer.Pop();
Console.Write("\b \b");
break;
case ConsoleKey.Backspace:
break;
case ConsoleKey.Escape:
Console.WriteLine();
return "";
default:
if (!char.IsControl(key.KeyChar))
{
buffer.Push(key.KeyChar);
Console.Write('*');
}
break;
}
}
}
}