using Insight.Domain.Constants;
using Insight.Infrastructure;
using Insight.Web.Hosting;
using Insight.Web.Interfaces;
using Insight.Web.Messages;
using Insight.Web.Middleware;
using Insight.Web.Network;
using Insight.Web.Network.Handlers;
using Vaitr.MemoryBus.Hosting;
using Vaitr.Network;
using static Insight.Web.Constants.Navigation.Management.Hosts.Systems;

namespace Insight.Web;

public class Program
{
    public static async Task Main(string[] args)
    {
        var builder = WebApplication.CreateBuilder(args);
        builder.Host.UseWindowsService(options => options.ServiceName = "insight_web");
        builder.Host.UseSystemd();

        // LOGGING
        builder.Logging.ClearProviders();
        builder.Logging.SetMinimumLevel(LogLevel.Trace);
        builder.Logging.AddFilter("Microsoft.AspNetCore", LogLevel.Error);
        builder.Logging.AddFilter("MudBlazor", LogLevel.Warning);

        builder.Logging.AddSimpleConsole(options =>
        {
            options.IncludeScopes = false;
            options.SingleLine = true;
            options.TimestampFormat = "yyyy-MM-dd HH:mm:ss.fff ";
        });

        builder.Logging.AddFile($"{Configuration.AppDirectory?.FullName}/" + "logs/web_{Date}.log", LogLevel.Trace, fileSizeLimitBytes: 104857600, retainedFileCountLimit: 10, outputTemplate: "{Timestamp:o} [{Level:u3}] {Message} {NewLine}{Exception}");

        // ASSETS
        builder.WebHost.UseStaticWebAssets();

        // INFRASTRUCTURE
        builder.Services.AddDatabase(builder.Configuration);
        builder.Services.AddInfrastructureServices();

        // IDENTITY
        builder.Services.AddIdentityServices(builder.Configuration);
        builder.Services.AddCustomAuthentication(builder.Configuration);
        builder.Services.AddMemoryBus();

        // SECURITY
        builder.Services.AddAuthorization();

        // WEBSERVICES
        builder.Services.AddWebServices();
        builder.Services.AddProxyServices(builder.Configuration);
        builder.Services.AddRoutingServices(builder.Configuration);
        builder.Services.AddSignalR(options =>
        {
            options.EnableDetailedErrors = true;
        });

        // NETWORKING
        //builder.Services.UseHostedTcpClient<WebSession, MemPackSerializer, IWebMessage>(options =>
        //{
        //    options.Host = builder.Configuration.GetValue<string?>(Appsettings.ServerHost) ?? throw new Exception($"{Appsettings.ServerHost} value not set (appsettings)");
        //    options.Port = builder.Configuration.GetValue<int?>(Appsettings.ServerPort) ?? throw new Exception($"{Appsettings.ServerPort} value not set (appsettings)");
        //    options.KeepAlive = 10000;
        //    options.Timeout = 30000;
        //    options.Buffer = 1024 * 1024;
        //    options.Parallelism = 0;
        //    options.Compression = Compression.None;
        //    options.Encryption = Encryption.Tls12;
        //    options.SslPolicy = SslPolicy.None;

        //    //options.InputRateLimit = 1024 * 1024 * 100;
        //    //options.OutputRateLimit = 1024 * 1024 * 100;
        //});

        //builder.Services.AddSingleton<IWebMessageHandler<WebSession>, ConsoleHandler>();

        // WEB:APP
        var app = builder.Build();

        // BASICS
        app.UseForwardedHeaders();
        //app.UseHttpsRedirection();

        // DEV-PROD SETTINGS
        if (app.Environment.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Error");
            //app.UseHsts();
        }

        // CORS
        //app.UseCors(x => x
        //    .AllowAnyOrigin()
        //    .AllowAnyMethod()
        //    .AllowAnyHeader());

        // ROUTING
        app.UseRouting();

        // SECURITY
        //app.UseAuthentication();
        app.UseAuthorization();

        // MIDDLEWARE
        app.UseMiddleware<IdentityMiddleware>();

        // BLAZOR HUBS (SIGNALR)
        app.MapBlazorHub();

        // FALLBACK
        app.MapFallbackToPage("/_Host");

        // STATIC FILES
        app.UseStaticFiles();

        // HOST START
        await app.RunAsync().ConfigureAwait(false);
    }
}