using Deploymentcenter.Client;
using Predictalytics.Hosting;
namespace Predictalytics.Shell.Services;
///
/// Lizenzverwaltung von der Kommandozeile — die im Deploymentcenter-Integrations-
/// leitfaden vorgesehenen Schalter. Gedacht fuer Server ohne Oberflaeche, wo es
/// keinen Aktivierungsdialog geben kann.
///
internal static class LicenseCli
{
public const string StatusSwitch = "--license-status";
public const string SetKeySwitch = "--license-set-key";
public const string DeactivateSwitch = "--license-deactivate";
public static bool IsLicenseCommand(string[] args) =>
args.Length > 0 && args[0] is StatusSwitch or SetKeySwitch or DeactivateSwitch;
public static async Task RunAsync(string[] args)
{
LicenseClient.DefaultAppVersion = DcConfig.AppVersion;
return args[0] switch
{
StatusSwitch => await ShowStatusAsync(),
SetKeySwitch => await SetKeyAsync(args.Length > 1 ? args[1] : null),
DeactivateSwitch => await DeactivateAsync(),
_ => HeadlessRunner.ExitFailed
};
}
private static async Task ShowStatusAsync()
{
var hw = LicenseGuard.GetHardwareInfo();
Console.WriteLine("Predictalytics — Lizenzstatus");
Console.WriteLine($" Produkt : {DcConfig.ProductSlug}");
Console.WriteLine($" Version : {DcConfig.AppVersion} ({DcConfig.GitCommitShort})");
Console.WriteLine($" Server : {DcConfig.BaseUrl}");
Console.WriteLine($" Hardware-ID : {hw.HardwareId}");
Console.WriteLine($" HWID-Quelle : {hw.HwidSource} (v{hw.HwidVersion}, {hw.Platform})");
Console.WriteLine($" Cache-Ablage : {LicenseGuard.StorageDirectory}");
var cachedKey = LicenseClient.TryGetCachedKey(DcConfig.ProductSlug);
if (string.IsNullOrWhiteSpace(cachedKey))
{
Console.WriteLine(" Schlüssel : keiner hinterlegt");
Console.WriteLine();
Console.WriteLine($"Aktivierung: {SetKeySwitch} ");
return HeadlessRunner.ExitNoLicense;
}
Console.WriteLine($" Schlüssel : {Mask(cachedKey!)}");
Console.WriteLine();
Console.Write("Prüfe am Deployment Center… ");
var check = await LicenseGuard.TryUseCachedAsync();
var result = check.LastResult;
if (check.IsUsable)
{
Console.WriteLine($"gültig ({result!.Status}{(result.IsCached ? ", aus lokalem Cache" : "")})");
if (result.CacheExpiresAt is { } expiresAt && expiresAt > 0)
{
Console.WriteLine($" Offline-Gnadenfrist bis: {DateTimeOffset.FromUnixTimeSeconds(expiresAt).UtcDateTime:yyyy-MM-dd HH:mm} UTC");
}
return HeadlessRunner.ExitOk;
}
// Transient heisst: kein Urteil, nur eine gescheiterte Verbindung.
Console.WriteLine(result?.IsTransient == true
? $"unentschieden ({result.Status}): {result.Message}"
: $"NICHT gültig ({result?.Status}): {result?.Message}");
return HeadlessRunner.ExitNoLicense;
}
private static async Task SetKeyAsync(string? key)
{
if (string.IsNullOrWhiteSpace(key))
{
Console.Error.WriteLine($"Aufruf: {SetKeySwitch} ");
return HeadlessRunner.ExitFailed;
}
Console.Write($"Aktiviere {Mask(key.Trim().ToUpperInvariant())} … ");
var (session, result) = await LicenseGuard.ActivateAsync(LicenseGuard.CreateClient(), key);
if (session is not null)
{
Console.WriteLine($"erfolgreich ({result.Status})");
Console.WriteLine($"Hardware-ID: {result.HardwareId}");
return HeadlessRunner.ExitOk;
}
Console.Error.WriteLine($"fehlgeschlagen ({result.Status}): {result.Message}");
return HeadlessRunner.ExitNoLicense;
}
private static async Task DeactivateAsync()
{
var key = LicenseClient.TryGetCachedKey(DcConfig.ProductSlug);
if (string.IsNullOrWhiteSpace(key))
{
Console.Error.WriteLine("Kein hinterlegter Schlüssel — nichts zu deaktivieren.");
return HeadlessRunner.ExitFailed;
}
Console.Write("Gebe Aktivierungsplatz am Deployment Center frei… ");
var ok = await LicenseGuard.CreateClient()
.DeactivateAsync(DcConfig.ProductSlug, key!, DcConfig.BaseUrl);
Console.WriteLine(ok ? "erfolgreich" : "fehlgeschlagen");
return ok ? HeadlessRunner.ExitOk : HeadlessRunner.ExitFailed;
}
/// Nur die Segmentstruktur zeigen, nicht den vollstaendigen Schluessel.
private static string Mask(string key)
{
var parts = key.Split('-');
if (parts.Length < 2) return "*****";
for (var i = 1; i < parts.Length - 1; i++) parts[i] = new string('*', parts[i].Length);
return string.Join('-', parts);
}
}