using System.IO; using System.Net.Http; using System.Reflection; using System.Text; using System.Text.Unicode; using System.Windows; using System.Windows.Threading; using Azaion.Annotator; using Azaion.Common; using Azaion.Common.Database; using Azaion.Common.DTO; using Azaion.Common.DTO.Config; using Azaion.Common.Events; using Azaion.Common.Extensions; using Azaion.Common.Services; using Azaion.CommonSecurity; using Azaion.CommonSecurity.DTO; using Azaion.CommonSecurity.DTO.Commands; using Azaion.CommonSecurity.Services; using Azaion.Dataset; using LazyCache; using LibVLCSharp.Shared; using MediatR; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using Newtonsoft.Json; using Serilog; using KeyEventArgs = System.Windows.Input.KeyEventArgs; namespace Azaion.Suite; public partial class App { private IHost _host = null!; private ILogger _logger = null!; private IMediator _mediator = null!; private FormState _formState = null!; private IInferenceClient _inferenceClient = null!; private IResourceLoader _resourceLoader = null!; private Stream _securedConfig = null!; private Stream _systemConfig = null!; private static readonly Guid KeyPressTaskId = Guid.NewGuid(); private readonly ICache _cache = new MemoryCache(); private readonly IHardwareService _hardwareService = new HardwareService(); private IAzaionApi _azaionApi = null!; private void OnDispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e) { _logger.LogError(e.Exception, e.Exception.Message); e.Handled = true; } protected override void OnStartup(StartupEventArgs e) { base.OnStartup(e); StartLogin(); } private readonly List _encryptedResources = [ "Azaion.Annotator", "Azaion.Dataset" ]; private static SecureAppConfig ReadSecureAppConfig() { try { if (!File.Exists(SecurityConstants.CONFIG_PATH)) throw new FileNotFoundException(SecurityConstants.CONFIG_PATH); var configStr = File.ReadAllText(SecurityConstants.CONFIG_PATH); var config = JsonConvert.DeserializeObject(configStr); return config ?? SecurityConstants.DefaultSecureAppConfig; } catch (Exception e) { Console.WriteLine(e); return SecurityConstants.DefaultSecureAppConfig; } } private void StartLogin() { new ConfigUpdater().CheckConfig(); var secureAppConfig = ReadSecureAppConfig(); _inferenceClient = new InferenceClient(new OptionsWrapper(secureAppConfig.InferenceClientConfig)); _resourceLoader = new ResourceLoader(_inferenceClient); var login = new Login(); login.CredentialsEntered += async (_, credentials) => { credentials.Folder = secureAppConfig.DirectoriesConfig.ApiResourcesDirectory; _inferenceClient.Send(RemoteCommand.Create(CommandType.Login, credentials)); _azaionApi = new AzaionApi(new HttpClient { BaseAddress = new Uri(SecurityConstants.API_URL) }, _cache, credentials, _hardwareService); try { _securedConfig = _resourceLoader.LoadFile("config.secured.json"); _systemConfig = _resourceLoader.LoadFile("config.system.json"); } catch (Exception e) { Console.WriteLine(e); _securedConfig = new MemoryStream("{}"u8.ToArray()); var systemConfig = new { AnnotationConfig = Constants.DefaultAnnotationConfig, AIRecognitionConfig = Constants.DefaultAIRecognitionConfig, ThumbnailConfig = Constants.DefaultThumbnailConfig, }; _systemConfig = new MemoryStream(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(systemConfig))); } AppDomain.CurrentDomain.AssemblyResolve += (_, a) => { var assemblyName = a.Name.Split(',').First(); if (_encryptedResources.Contains(assemblyName)) { try { var stream = _resourceLoader.LoadFile($"{assemblyName}.dll"); return Assembly.Load(stream.ToArray()); } catch (Exception e) { Console.WriteLine(e); var currentLocation = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)!; var dllPath = Path.Combine(currentLocation, SecurityConstants.DUMMY_DIR, $"{assemblyName}.dll"); return Assembly.LoadFile(dllPath); } } var loadedAssembly = AppDomain.CurrentDomain.GetAssemblies() .FirstOrDefault(a => a.GetName().Name == assemblyName); return loadedAssembly; }; StartMain(); _host.Start(); EventManager.RegisterClassHandler(typeof(UIElement), UIElement.KeyDownEvent, new RoutedEventHandler(GlobalClick)); _host.Services.GetRequiredService().Show(); }; login.ShowDialog(); } private void StartMain() { Log.Logger = new LoggerConfiguration() .Enrich.FromLogContext() .MinimumLevel.Information() .WriteTo.Console() .WriteTo.File( path: "Logs/log.txt", rollingInterval: RollingInterval.Day) .CreateLogger(); _host = Host.CreateDefaultBuilder() .ConfigureAppConfiguration((context, config) => config .AddCommandLine(Environment.GetCommandLineArgs()) .AddJsonFile(SecurityConstants.CONFIG_PATH, optional: true, reloadOnChange: true) .AddJsonStream(_securedConfig) .AddJsonStream(_systemConfig)) .UseSerilog() .ConfigureServices((context, services) => { services.AddSingleton(); services.AddSingleton(); services.Configure(context.Configuration); services.ConfigureSection(context.Configuration); services.ConfigureSection(context.Configuration); services.ConfigureSection(context.Configuration); services.ConfigureSection(context.Configuration); services.ConfigureSection(context.Configuration); services.ConfigureSection(context.Configuration); #region External Services services.ConfigureSection(context.Configuration); services.ConfigureSection(context.Configuration); services.AddSingleton(_inferenceClient); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddHttpClient(); services.AddSingleton(_azaionApi); #endregion services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddMediatR(c => c.RegisterServicesFromAssemblies( typeof(Annotator.Annotator).Assembly, typeof(DatasetExplorer).Assembly, typeof(AnnotationService).Assembly)); services.AddSingleton(_ => new LibVLC()); services.AddSingleton(); services.AddSingleton(sp => { var libVLC = sp.GetRequiredService(); return new MediaPlayer(libVLC); }); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); }) .Build(); Annotation.InitializeDirs(_host.Services.GetRequiredService>().Value); _mediator = _host.Services.GetRequiredService(); _logger = _host.Services.GetRequiredService>(); _formState = _host.Services.GetRequiredService(); DispatcherUnhandledException += OnDispatcherUnhandledException; } private void GlobalClick(object sender, RoutedEventArgs e) { var args = (KeyEventArgs)e; var keyEvent = new KeyEvent(sender, args, _formState.ActiveWindow); ThrottleExt.Throttle(() => _mediator.Publish(keyEvent), KeyPressTaskId, TimeSpan.FromMilliseconds(50)); } protected override async void OnExit(ExitEventArgs e) { base.OnExit(e); await _host.StopAsync(); } }