using System.IO; using System.Net.Http; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Threading; using Azaion.Annotator; using Azaion.Annotator.DTO; using Azaion.Annotator.Extensions; using Azaion.Common; using Azaion.Common.DTO; using Azaion.Common.DTO.Config; using Azaion.Common.Extensions; using Azaion.Common.Services; using Azaion.Dataset; using CommandLine; 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; namespace Azaion.Suite; public partial class App { private readonly IHost _host; private readonly ILogger _logger; private readonly IMediator _mediator; //Authorize to api and private static readonly IResourceLoader ResourceLoader; static App() { new ConfigUpdater().CheckConfig(); var result = Parser.Default.ParseArguments(Environment.GetCommandLineArgs()); var apiCreds = !result.Errors.Any() ? result.Value : new ApiCredentials(); ResourceLoader = new ResourceLoader(CreateApiClient(apiCreds), apiCreds); //AppDomain.CurrentDomain.AssemblyResolve += (_, args) => ResourceLoader.LoadAssembly(args.Name); } private static AzaionApiClient CreateApiClient(ApiCredentials credentials) { ApiConfig apiConfig; try { if (!File.Exists(Constants.CONFIG_PATH)) throw new FileNotFoundException(Constants.CONFIG_PATH); var configStr = File.ReadAllText(Constants.CONFIG_PATH); apiConfig = JsonConvert.DeserializeObject(configStr)!.ApiConfig; } catch (Exception e) { Console.WriteLine(e); apiConfig = new ApiConfig { Url = "https://api.azaion.com", RetryCount = 3, TimeoutSeconds = 40 }; } var api = new AzaionApiClient(new HttpClient { BaseAddress = new Uri(apiConfig.Url), Timeout = TimeSpan.FromSeconds(apiConfig.TimeoutSeconds) }); api.EnterCredentials(credentials); return api; } public App() { 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(Constants.CONFIG_PATH, optional: true, reloadOnChange: true)) .ConfigureServices((context, services) => { services.AddSingleton(); services.AddSingleton(); services.AddSingleton(ResourceLoader); 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); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddMediatR(c => c.RegisterServicesFromAssemblies( typeof(Annotator.Annotator).Assembly, typeof(DatasetExplorer).Assembly)); services.AddSingleton(_ => new LibVLC()); services.AddSingleton(); services.AddSingleton(sp => { var libVLC = sp.GetRequiredService(); return new MediaPlayer(libVLC); }); services.AddSingleton(); services.AddSingleton(); services.AddHttpClient((sp, client) => { var apiConfig = sp.GetRequiredService>().Value; client.BaseAddress = new Uri(apiConfig.Url); client.Timeout = TimeSpan.FromSeconds(apiConfig.TimeoutSeconds); }); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); }) .Build(); _mediator = _host.Services.GetRequiredService(); _logger = _host.Services.GetRequiredService>(); DispatcherUnhandledException += OnDispatcherUnhandledException; } private void OnDispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e) { _logger.LogError(e.Exception, e.Exception.Message); e.Handled = true; } protected override async void OnStartup(StartupEventArgs e) { EventManager.RegisterClassHandler(typeof(UIElement), UIElement.KeyDownEvent, new RoutedEventHandler(GlobalClick)); await _host.StartAsync(); _host.Services.GetRequiredService().Show(); base.OnStartup(e); } private void GlobalClick(object sender, RoutedEventArgs e) { var args = (KeyEventArgs)e; var windowEnum = GetParentWindow(sender as FrameworkElement); if (windowEnum == WindowEnum.None) return; var keyEvent = new KeyEvent(sender, args, windowEnum); _ = ThrottleExt.Throttle(() => _mediator.Publish(keyEvent), TimeSpan.FromMilliseconds(50)); } private WindowEnum GetParentWindow(FrameworkElement? element) { if (element?.GetType().Name == "LibVLCSharp.WPF.ForegroundWindow") return WindowEnum.Annotator; while (element != null && element is not TabItem) element = element.Parent as FrameworkElement; if (element is not TabItem || element.Tag == null) return WindowEnum.None; return (WindowEnum)element.Tag; } protected override async void OnExit(ExitEventArgs e) { base.OnExit(e); await _host.StopAsync(); //_host.Dispose(); } }