namespace ClawdDotNet.App.Services;
///
/// Wie der mit dem Benutzer spricht.
///
/// Vorher rief er unmittelbar MessageBox.Show und einen WinForms-Dialog.
/// Das band die Lizenzprüfung an WinForms — und wäre im kopflosen Betrieb fatal
/// gewesen: Ein Dienst, der beim Start ein Fenster öffnet und auf eine Eingabe wartet,
/// hängt für immer, ohne dass jemand die Meldung je zu sehen bekäme.
///
/// Es gibt drei Umsetzungen:
///
/// - AvaloniaLicensePrompt — Dialoge im Fenster (Desktop).
/// - — Eingabe über die Konsole (Kommandozeile).
/// - — antwortet nie (systemd-Dienst).
///
///
public interface ILicensePrompt
{
///
/// Fragt einen Lizenzschlüssel ab. null heißt Abbruch — der Aufrufer beendet
/// die Anwendung.
///
/// Wird angezeigt, damit der Nutzer ihn an den Support geben kann.
/// Warum der bisherige Schlüssel nicht taugt; null beim ersten Fragen.
/// Vorbelegung des Eingabefelds.
Task RequestKeyAsync(string hardwareId, string? problem, string? currentKey);
/// Eine Meldung, die keine Antwort braucht (etwa „offline gültig bis …").
Task ShowInfoAsync(string title, string message);
/// Ein Fehler, nach dem die Anwendung nicht weiterläuft.
Task ShowErrorAsync(string title, string message);
}
///
/// Für den kopflosen Betrieb: fragt nicht, sondern lehnt ab.
///
/// Ein Dienst ohne Sitzung kann keinen Schlüssel entgegennehmen. Statt zu blockieren
/// meldet er, was zu tun ist — der Schlüssel wird vorab über die Kommandozeile
/// hinterlegt (--license-set-key).
///
public sealed class NonInteractiveLicensePrompt(Action log) : ILicensePrompt
{
public Task RequestKeyAsync(string hardwareId, string? problem, string? currentKey)
{
log($"Lizenz erforderlich, aber kein Eingabeweg vorhanden. Hardware-ID: {hardwareId}. "
+ (problem is null ? "" : $"Grund: {problem}. ")
+ "Schlüssel mit '--license-set-key ' hinterlegen.");
return Task.FromResult(null);
}
public Task ShowInfoAsync(string title, string message)
{
log($"{title}: {message}");
return Task.CompletedTask;
}
public Task ShowErrorAsync(string title, string message)
{
log($"{title}: {message}");
return Task.CompletedTask;
}
}
/// Eingabe über die Konsole — für Kommandozeilenaufrufe.
public sealed class ConsoleLicensePrompt : ILicensePrompt
{
public Task RequestKeyAsync(string hardwareId, string? problem, string? currentKey)
{
if (problem is not null)
Console.Error.WriteLine($"Lizenz: {problem}");
Console.WriteLine($"Hardware-ID: {hardwareId}");
Console.Write("Lizenzschlüssel: ");
var input = Console.ReadLine()?.Trim();
return Task.FromResult(string.IsNullOrWhiteSpace(input) ? null : input);
}
public Task ShowInfoAsync(string title, string message)
{
Console.WriteLine($"{title}: {message}");
return Task.CompletedTask;
}
public Task ShowErrorAsync(string title, string message)
{
Console.Error.WriteLine($"{title}: {message}");
return Task.CompletedTask;
}
}