using octo_fiesta.Models.Settings; using octo_fiesta.Services; using octo_fiesta.Services.Deezer; using octo_fiesta.Services.Qobuz; using octo_fiesta.Services.Local; using octo_fiesta.Services.Validation; using octo_fiesta.Services.Subsonic; using octo_fiesta.Services.Common; using octo_fiesta.Middleware; var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddControllers(); builder.Services.AddHttpClient(); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); // Exception handling builder.Services.AddExceptionHandler(); builder.Services.AddProblemDetails(); // Configuration builder.Services.Configure( builder.Configuration.GetSection("Subsonic")); builder.Services.Configure( builder.Configuration.GetSection("Deezer")); builder.Services.Configure( builder.Configuration.GetSection("Qobuz")); // Get the configured music service var musicService = builder.Configuration.GetValue("Subsonic:MusicService"); // Business services // Registered as Singleton to share state (mappings cache, scan debounce, download tracking, rate limiting) builder.Services.AddSingleton(); // Subsonic services builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); // Register music service based on configuration if (musicService == MusicService.Qobuz) { // Qobuz services builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); } else { // Deezer services (default) builder.Services.AddSingleton(); builder.Services.AddSingleton(); } // Startup validation - register validators builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); // Register orchestrator as hosted service builder.Services.AddHostedService(); // Register cache cleanup service (only runs when StorageMode is Cache) builder.Services.AddHostedService(); builder.Services.AddCors(options => { options.AddDefaultPolicy(policy => { policy.AllowAnyOrigin() .AllowAnyMethod() .AllowAnyHeader() .WithExposedHeaders("X-Content-Duration", "X-Total-Count", "X-Nd-Authorization"); }); }); var app = builder.Build(); // Configure the HTTP request pipeline. app.UseExceptionHandler(_ => { }); // Global exception handler if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } app.UseHttpsRedirection(); app.UseAuthorization(); app.UseCors(); app.MapControllers(); app.Run();