using System.Diagnostics; using System.IO; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media; using MessagePack; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using NetMQ; using NetMQ.Sockets; namespace Azaion.LoaderUI; public partial class Login { private readonly IAzaionApi _azaionApi; private readonly ILogger _logger; private readonly DirectoriesConfig? _dirConfig; public Login(IAzaionApi azaionApi, IOptions directoriesConfig, ILogger logger) { _azaionApi = azaionApi; _logger = logger; _dirConfig = directoriesConfig.Value; InitializeComponent(); } private void SetControlsStatus(bool isLoading) { LoginBtn.IsEnabled = !isLoading; TbEmail.IsEnabled = !isLoading; TbPassword.IsEnabled = !isLoading; LoginBtn.Cursor = isLoading ? Cursors.Wait : Cursors.Arrow; Cursor = isLoading ? Cursors.Wait : Cursors.Arrow; } private async void LoginClick(object sender, RoutedEventArgs e) { var creds = new ApiCredentials { Email = TbEmail.Text, Password = TbPassword.Password }; if (!creds.IsValid()) return; SetControlsStatus(isLoading: true); _azaionApi.Login(creds); try { Validate(creds); } catch (Exception exception) { _logger.LogError(exception, exception.Message); TbStatus.Foreground = Brushes.Red; TbStatus.Text = exception.Message; SetControlsStatus(isLoading: false); return; } TbStatus.Foreground = Brushes.Black; var installerVersion = await GetInstallerVer(); var localVersion = GetLocalVer(); if (installerVersion > localVersion) { TbStatus.Text = $"Updating from {localVersion} to {installerVersion}..."; await DownloadAndRunInstaller(); TbStatus.Text = $"Installed {installerVersion}!"; } else TbStatus.Text = "Your version is up to date!"; Process.Start(Constants.AZAION_SUITE_EXE, $"-e {creds.Email} -p {creds.Password}"); await Task.Delay(800); TbStatus.Text = "Loading..."; while (!Process.GetProcessesByName(Constants.INFERENCE_EXE).Any()) await Task.Delay(500); await Task.Delay(1500); Close(); } private void Validate(ApiCredentials creds) { var dealer = new DealerSocket(); try { using var process = new Process(); process.StartInfo = new ProcessStartInfo { FileName = Constants.EXTERNAL_LOADER_PATH, Arguments = $"--port {Constants.EXTERNAL_LOADER_PORT} --api {Constants.API_URL}", CreateNoWindow = true }; process.Start(); dealer.Options.Identity = Encoding.UTF8.GetBytes(Guid.NewGuid().ToString("N")); dealer.Connect($"tcp://{Constants.EXTERNAL_LOADER_HOST}:{Constants.EXTERNAL_LOADER_PORT}"); var result = SendCommand(dealer, RemoteCommand.Create(CommandType.Login, creds)); if (result.CommandType != CommandType.Ok) throw new Exception(result.Message); result = SendCommand(dealer, RemoteCommand.Create(CommandType.CheckResource)); if (result.CommandType != CommandType.Ok) throw new Exception(result.Message); } catch (Exception e) { _logger.LogError(e, e.Message); throw; } finally { SendCommand(dealer, RemoteCommand.Create(CommandType.Exit)); dealer.Close(); dealer.Dispose(); } } private RemoteCommand SendCommand(DealerSocket dealer, RemoteCommand command, int retryCount = 30, int retryDelayMs = 800) { try { dealer.SendFrame(MessagePackSerializer.Serialize(command)); var tryNum = 0; while (tryNum++ < retryCount) { if (!dealer.TryReceiveFrameBytes(TimeSpan.FromMilliseconds(retryDelayMs), out var bytes)) continue; var res = MessagePackSerializer.Deserialize(bytes); if (res.CommandType == CommandType.Error) throw new Exception(res.Message); return res; } throw new Exception($"Sent {command} {retryCount} times, with wait time {retryDelayMs}ms for each call. No response from client."); } catch (Exception e) { _logger.LogError(e, e.Message); throw; } } private async Task DownloadAndRunInstaller() { var (installerName, stream) = await _azaionApi.DownloadInstaller(_dirConfig?.SuiteInstallerDirectory ?? ""); var localFileStream = new FileStream(installerName, FileMode.Create, FileAccess.Write); await stream.CopyToAsync(localFileStream); localFileStream.Close(); stream.Close(); var processInfo = new ProcessStartInfo(installerName) { UseShellExecute = true, Arguments = "/VERYSILENT" }; var process = Process.Start(processInfo); await process!.WaitForExitAsync(); File.Delete(installerName); } private async Task GetInstallerVer() { TbStatus.Text = "Checking for the newer version..."; var installerName = await _azaionApi.GetLastInstallerName(_dirConfig?.SuiteInstallerDirectory ?? Constants.SUITE_FOLDER); var version = installerName .Replace("AzaionSuite.Iterative.", "") .Replace(".exe", ""); return new Version(version); } private Version GetLocalVer() { var localFileInfo = FileVersionInfo.GetVersionInfo(Constants.AZAION_SUITE_EXE); if (string.IsNullOrWhiteSpace(localFileInfo.ProductVersion)) throw new Exception($"Can't find {Constants.AZAION_SUITE_EXE} and its version"); return new Version(localFileInfo.FileVersion!); } private void CloseClick(object sender, RoutedEventArgs e) => Close(); private void MainMouseMove(object sender, MouseEventArgs e) { if (e.OriginalSource is Button || e.OriginalSource is TextBox) return; if (e.LeftButton == MouseButtonState.Pressed) DragMove(); } }