using MailPrint;
using MailPrint.Services;
using Serilog;
using Serilog.Events;

// Working directory auf EXE-Verzeichnis setzen
Directory.SetCurrentDirectory(AppContext.BaseDirectory);

Log.Logger = new LoggerConfiguration()
    .MinimumLevel.Information()
    .MinimumLevel.Override("Microsoft", LogEventLevel.Warning)
    .MinimumLevel.Override("Microsoft.AspNetCore", LogEventLevel.Warning)
    .WriteTo.Console(outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj}{NewLine}{Exception}")
    .WriteTo.File(
        Path.Combine(AppContext.BaseDirectory, "logs", "mailprint-.log"),
        rollingInterval: RollingInterval.Day,
        retainedFileCountLimit: 30)
    .CreateLogger();

try
{
    Log.Information("MailPrint gestartet. Beenden mit Ctrl+C.");

    var builder = WebApplication.CreateBuilder(args);

    // Als Windows Service UND als Konsole nutzbar
    builder.Host.UseWindowsService(options => options.ServiceName = "MailPrint");

    builder.Host.UseSerilog();

    builder.Configuration
        .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
        .AddJsonFile($"appsettings.{builder.Environment.EnvironmentName}.json", optional: true)
        .AddEnvironmentVariables();

    builder.WebHost.ConfigureKestrel(kestrel =>
    {
        var port = builder.Configuration.GetValue<int>("MailPrint:WebApi:Port", 5100);
        var bindAll = builder.Configuration.GetValue<bool>("MailPrint:WebApi:BindAllInterfaces", false);
        if (bindAll)
            kestrel.ListenAnyIP(port);
        else
            kestrel.ListenLocalhost(port);
    });

    builder.Services.Configure<MailPrintOptions>(builder.Configuration.GetSection("MailPrint"));
    builder.Services.AddSingleton<PrintService>();
    builder.Services.AddSingleton<MailFetchService>();
    builder.Services.AddSingleton<FolderWatcherService>();
    builder.Services.AddHostedService<MailPrintWorker>();
    builder.Services.AddControllers();
    builder.Services.AddEndpointsApiExplorer();
    builder.Services.AddSwaggerGen(c =>
    {
        c.SwaggerDoc("v1", new() { Title = "MailPrint API", Version = "v1" });

        // XML-Doku aus /// Kommentaren in OpenAPI uebernehmen
        var xmlPath = Path.Combine(AppContext.BaseDirectory, "MailPrint.xml");
        if (File.Exists(xmlPath))
            c.IncludeXmlComments(xmlPath);

        // API-Key-Security im Schema dokumentieren -> generierte Clients
        // setzen den Header automatisch, Swagger UI hat Authorize-Button
        var scheme = new Microsoft.OpenApi.Models.OpenApiSecurityScheme
        {
            Name = "X-Api-Key",
            Type = Microsoft.OpenApi.Models.SecuritySchemeType.ApiKey,
            In = Microsoft.OpenApi.Models.ParameterLocation.Header,
            Description = "API-Key fuer alle /api/* Endpunkte. Konfiguriert in MailPrintConfig.",
            Reference = new Microsoft.OpenApi.Models.OpenApiReference
            {
                Type = Microsoft.OpenApi.Models.ReferenceType.SecurityScheme,
                Id = "ApiKey"
            }
        };
        c.AddSecurityDefinition("ApiKey", scheme);
        c.AddSecurityRequirement(new Microsoft.OpenApi.Models.OpenApiSecurityRequirement
        {
            [scheme] = Array.Empty<string>()
        });
    });

    var app = builder.Build();
    app.UseSwagger();
    app.UseSwaggerUI();
    app.UseMiddleware<ApiKeyMiddleware>();
    app.MapControllers();

    await app.RunAsync();
}
catch (Exception ex) when (ex is not OperationCanceledException)
{
    Log.Fatal(ex, "Unbehandelter Fehler");
    return 1;
}
finally
{
    Log.CloseAndFlush();
}

return 0;
