using Microsoft.AspNetCore.Http.Features;
using Microsoft.Extensions.FileProviders;
using Newtonsoft.Json;
using NLog;
using NLog.Web;

// Early init of NLog to allow startup and exception logging, before host is built
var logger = NLog.LogManager.Setup()
                      .LoadConfigurationFromAppSettings()
                      .GetCurrentClassLogger();
logger.Debug("Init Main...");

try
{
    var builder = WebApplication.CreateBuilder(args);

    // Services Settings
    // Add services to the container.
    // builder.Services.AddControllersWithViews();

    // NLog: Setup NLog for Dependency injection
    builder.Logging.ClearProviders();
    builder.Host.UseNLog();
    builder.Services.AddEndpointsApiExplorer();

    builder.Services.Configure<FormOptions>(options =>
    {
        options.MultipartBodyLengthLimit = 32 * 1024 * 1024;
    });

    // Add Json.Net Serializer
    builder.Services.AddControllersWithViews().AddNewtonsoftJson(options =>
    {
        // Configure Newtonsoft.Json options here
        options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
        options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
    });

    // Add CORS policy
    if (builder.Environment.IsDevelopment())
    {
        builder.Services.AddCors(options =>
        {
            options.AddPolicy("Development", policy => policy
                .AllowAnyOrigin()
                .AllowAnyMethod()
                .AllowAnyHeader()
            );
        });
    }
    builder.Services.AddCors(options =>
    {
        options.AddPolicy("Users", policy => policy
            .AllowAnyOrigin()
        );
    });

    // Add Swagger
    builder.Services.AddControllers();
    builder.Services.AddOpenApiDocument(options =>
    {
        options.PostProcess = document =>
        {
            document.Info = new NSwag.OpenApiInfo
            {
                Version = "v1",
                Title = "FPGA Web Lab API",
                Description = "Use FPGA in the cloud",
                // TermsOfService = "https://example.com/terms",
                // Contact = new NSwag.OpenApiContact
                // {
                //     Name = "Example Contact",
                //     Url = "https://example.com/contact"
                // },
                // License = new NSwag.OpenApiLicense
                // {
                //     Name = "Example License",
                //     Url = "https://example.com/license"
                // }
            };
        };
    });

    // Application Settings
    var app = builder.Build();
    // Configure the HTTP request pipeline.
    if (!app.Environment.IsDevelopment())
    {
        // app.UseExceptionHandler("/Home/Error");
        // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
        app.UseHsts();

        // Serve static files
        logger.Info($"Use Static Files : {Path.Combine(Directory.GetCurrentDirectory(), "wwwroot")}");
        app.UseDefaultFiles();
        app.UseStaticFiles(); // Serves files from wwwroot by default
        // Assets Files
        app.UseStaticFiles(new StaticFileOptions
        {
            FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "assets")),
            RequestPath = "/assets"
        });
        // Log Files
        if (!Directory.Exists(Path.Combine(Directory.GetCurrentDirectory(), "log")))
        {
            Directory.CreateDirectory(Path.Combine(Directory.GetCurrentDirectory(), "log"));
        }
        app.UseStaticFiles(new StaticFileOptions
        {
            FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "log")),
            RequestPath = "/log"
        });
        app.MapFallbackToFile("index.html");
    }
    // Add logs
    app.UseHttpsRedirection();
    app.UseRouting();
    app.UseCors();
    app.UseAuthorization();

    // Swagger
    app.UseOpenApi();
    app.UseSwaggerUi();

    // Router
    app.MapControllers();

    // Setup Program
    MsgBus.Init();

    app.Run();
}
catch (Exception exception)
{
    // NLog: catch setup errors
    logger.Error(exception, "Stopped program because of exception");
    throw;
}
finally
{
    // Close UDP Server
    logger.Info("Program is Closing now...");

    // Ensure to flush and stop internal timers/threads before application-exit (Avoid segmentation fault on Linux)
    NLog.LogManager.Shutdown();

    // Close Program
    MsgBus.Exit();
}

