using DSaC.Database;
using Microsoft.EntityFrameworkCore;
using Microsoft.OpenApi.Models;
using NLog.Config;
using NLog.Extensions.Logging;
using NLog.Targets;
using PIHelperSh.Configuration;
using PIHelperSh.Configuration.Attributes;
using System.Reflection;
using LogLevel = NLog.LogLevel;

[TrackedType]
public class Program
{
    private static WebApplication? app;

    [Constant(BlockName = "Database")]
    private static string ConnectionString;

    [Constant(BlockName = "GatewaySettings")]
    private static string AppPrefix;
    public static void Main(string[] args)
    {
        var builder = WebApplication.CreateBuilder(args);

        ConfigureLogger(builder);

        ConfigureServices(builder);

        ConfigureDatabase(builder);

        app = builder.Build();

        var t = MigrateDatabase();

        app.UseSwagger(c =>
        {
            if (!string.IsNullOrEmpty(AppPrefix))
            {
                //c.RouteTemplate = AppPrefix + "/swagger/{documentName}/swagger.json";

                c.PreSerializeFilters.Add((swaggerDoc, httpReq) =>
                {
                    swaggerDoc.Servers = new List<OpenApiServer> { new OpenApiServer { Url = $"{httpReq.Scheme}://{httpReq.Host.Value}/{AppPrefix}" } };
                });
            }
        });
        app.UseSwaggerUI(c =>
        {
            //if (!string.IsNullOrEmpty(AppPrefix))
            //{
            //    c.SwaggerEndpoint($"/{AppPrefix}/swagger/v1/swagger.json", $"APP API");
            //    c.RoutePrefix = $"{AppPrefix}/swagger";
            //}
        });

        app.UseHttpsRedirection();

        app.UseAuthorization();

        app.MapControllers();

        t.Wait();

        app.Run();
    }

    private static void ConfigureLogger(WebApplicationBuilder builder)
    {
        var nLogConfig = new LoggingConfiguration();
        var logConsole = new ConsoleTarget();
        var blackhole = new NullTarget();

        var logFile = new FileTarget()
        {
            FileName = "${basedir}/logs/${shortdate}_logs.log"
        };

        nLogConfig.AddRule(LogLevel.Trace, LogLevel.Trace, blackhole, "Microsoft.AspNetCore.*", true);
        nLogConfig.AddRule(LogLevel.Info, LogLevel.Warn, logFile, "Microsoft.EntityFrameworkCore.*", true);
        nLogConfig.AddRule(LogLevel.Info, LogLevel.Warn, logFile, "Microsoft.AspNetCore.*", true);
        nLogConfig.AddRule(LogLevel.Info, LogLevel.Warn, logFile, "System.Net.Http.HttpClient.Refit.*", true);
        nLogConfig.AddRule(LogLevel.Info, LogLevel.Error, logConsole);
        nLogConfig.AddRule(LogLevel.Debug, LogLevel.Error, logFile);

        builder.Logging.ClearProviders();
        builder.Services.AddLogging(m => m.AddNLog(nLogConfig));
    }

    private static void ConfigureServices(WebApplicationBuilder builder)
    {
        builder.Services.AddConfigurations(builder.Configuration);
        builder.Configuration.AddConstants();
        builder.Services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());

        builder.Services.AddMediatR(cfg => cfg.RegisterServicesFromAssemblyContaining<Program>());

        builder.Services.AddControllers().AddNewtonsoftJson();

        builder.Services.AddEndpointsApiExplorer();
        builder.Services.AddSwaggerGen(c =>
        {
            c.SwaggerDoc("v1", new OpenApiInfo
            {
                Title = "Distributed computing and applications",
                Version = "v1",
                Description = ""
            });

            //c.EnableAnnotations();
        });
    }

    private static void ConfigureDatabase(WebApplicationBuilder builder) 
    {
        builder.Services.AddDbContext<DsacContext>(options =>
        {
            options.UseNpgsql(ConnectionString);
        });
    }

    private static async Task MigrateDatabase()
    {
        var context = app?.Services.CreateScope().ServiceProvider.GetService<DsacContext>();
        if(context != null)
            await context.Database.MigrateAsync();
    }
}