using FellowOakDicom;
using IRaCIS.Core.API;
using IRaCIS.Core.API.HostService;
using IRaCIS.Core.Application.BusinessFilter;
using IRaCIS.Core.Application.BusinessFilter.LegacyController.Database.Api;
using IRaCIS.Core.Application.Filter;
using IRaCIS.Core.Application.Service;
using IRaCIS.Core.Infra.EFCore;
using IRaCIS.Core.Infrastructure.Extention;
using MassTransit;
using MassTransit.NewIdProviders;
using Newtonsoft.Json;
using Serilog;
using System.Globalization;
using System.Runtime.InteropServices;
using UAParser;

AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);
AppContext.SetSwitch("Npgsql.DisableDateTimeInfinityConversions", true);


Console.WriteLine("Startup Culture: " + CultureInfo.CurrentCulture.Name);
Console.WriteLine("Startup UI Culture: " + CultureInfo.CurrentUICulture.Name);

#region 获取环境变量
//以配置文件为准，否则 从url中取环境值(服务以命令行传递参数启动，配置文件配置了就不需要传递环境参数)
var config = new ConfigurationBuilder()
            .AddEnvironmentVariables()
            .Build();

var enviromentName = config["ASPNETCORE_ENVIRONMENT"];

var openSwaggerStr = config["ASPNETCORE_OpenSwagger"];

var isOpenSwagger= openSwaggerStr == null|| openSwaggerStr?.ToLower()=="true";


if (string.IsNullOrWhiteSpace(enviromentName))
{

    var index = Array.IndexOf(args, "--env");
    enviromentName = index > -1
        ? args[index + 1]
        : "Development";
}
#endregion

// Serilog 
SerilogExtension.AddSerilogSetup(enviromentName);

var builder = WebApplication.CreateBuilder(new WebApplicationOptions
{

    EnvironmentName = enviromentName,
    Args = args
});

#region 主机配置


NewId.SetProcessIdProvider(new CurrentProcessIdProvider());

builder.Configuration.AddJsonFile(ConfigMapFileProvider.FromRelativePath(""), "appsettings.json", false, true)
                     .AddJsonFile(ConfigMapFileProvider.FromRelativePath(""), $"appsettings.{enviromentName}.json", false, true);

builder.Host.UseSerilog();


#endregion


#region 配置服务
var _configuration = builder.Configuration;

//手动注册服务
builder.Services.ConfigureServices(_configuration);

builder.Services.AddHostedService<HangfireHostService>();

builder.Services.AddSingleton<FileSyncQueue>();
builder.Services.AddHostedService<SyncFileRecoveryService>();
builder.Services.AddHostedService<FileSyncWorker>();

builder.Services.AddSingleton(_ => Parser.GetDefault());

//minimal api 异常处理
builder.Services.AddExceptionHandler<GlobalExceptionHandler>();
//builder.Services.AddProblemDetails();

//健康检查
builder.Services.AddHealthChecks();
builder.Services.AddSerilog();
//本地化
builder.Services.AddJsonLocalization(options => options.ResourcesPath = new[] { "Resources" });

// 异常、参数统一验证过滤器、Json序列化配置、字符串参数绑型统一Trim()
builder.Services.AddControllers(options =>
{
    // 关键配置：禁用不可空引用类型的自动 Required 验证
    options.SuppressImplicitRequiredAttributeForNonNullableReferenceTypes = true;

    // 插到最前，抢在默认绑定器之前
    //options.ModelBinderProviders.Insert(0, new SpecificNullableBinderProvider());

    options.Filters.Add<ModelActionFilter>();
    options.Filters.Add<ProjectExceptionFilter>();
    options.Filters.Add<UnitOfWorkFilter>();
    options.Filters.Add<LimitUserRequestAuthorization>();
    options.Filters.Add<TrialGlobalLimitActionFilter>();
    options.Filters.Add<RequestDuplicationFilter>();

})
    .AddNewtonsoftJsonSetup(builder.Services); // NewtonsoftJson 序列化  处理

// Panda动态WebApi + UnifiedApiResultFilter + 省掉控制器代码
builder.Services.AddDynamicWebApiSetup();
//MinimalAPI
builder.Services.AddMasaMinimalAPiSetUp();

//AutoMapper
builder.Services.AddAutoMapperSetup();
//EF ORM  QueryWithNoLock
builder.Services.AddEFSetup(_configuration, enviromentName);
//Http 响应压缩
builder.Services.AddResponseCompressionSetup();

if (isOpenSwagger)
{
    //Swagger Api 文档
    builder.Services.AddSwaggerSetup();
}

//JWT Token 验证
builder.Services.AddJWTAuthSetup(_configuration);

//MassTransit
builder.Services.AddMassTransitSetup();

// FusionCache
builder.Services.AddFusionCache();

// hangfire  定时任务框架  有界面，更友好~
builder.Services.AddhangfireSetup(_configuration);

//Serilog 日志可视化 LogDashboard日志
//builder.Services.AddLogDashboardSetup();

//Dicom影像渲染图片  跨平台
builder.Services.AddDicomSetup();

// 实时应用
builder.Services.AddSignalR();


//// 添加反伪造服务
//builder.Services.AddAntiforgery(options =>
//{
//    // 可选：设置自定义的头部名称以支持 AJAX 请求等
//    options.HeaderName = "X-XSRF-TOKEN";
//});

//builder.Services.AddAntiforgery();

#endregion

var app = builder.Build();
var env = app.Environment;

#region 配置中间件

DicomSetupBuilder.UseServiceProvider(app.Services);

app.UseMiddleware<EncryptionRequestMiddleware>();

#region 异常处理  全局业务异常已统一处理了，非业务错误会来到这里  400 -500状态码


//app.UseStatusCodePagesWithReExecute("/Error/{0}");

app.UseStatusCodePages(async context =>
{
    var code = context.HttpContext.Response.StatusCode;
    context.HttpContext.Response.ContentType = "application/json";
    if (code < 500)
    {
        await context.HttpContext.Response.WriteAsync(JsonConvert.SerializeObject(ResponseOutput.NotOk($"Client error, actual request error status code({code})")));
    }
    else
    {
        //ResultFilter 里面的异常并不会到这里
        await context.HttpContext.Response.WriteAsync(JsonConvert.SerializeObject((ResponseOutput.NotOk($"Server error , actual request error status code({code})"))));
    }

});

//app.UseExceptionHandler();
app.UseExceptionHandler(o => { });

#region 暂时废弃

//app.UseMiddleware<MultiDiskStaticFilesMiddleware>();
////限流 中间件
//app.UseIpRateLimiting();
//if (env.IsDevelopment())
//{
//    app.UseDeveloperExceptionPage();
//}
//else
//{
//    //app.UseHsts();
//}

//app.UseIRacisHostStaticFileStore(env);
#endregion

#endregion

app.UseIRacisHostStaticFileStore(env);

//本地化
await app.UseLocalization(app.Services);

app.UseForwardedHeaders();

//响应压缩
app.UseResponseCompression();

//不需要 token 访问的静态文件  wwwroot css, JavaScript, and images don't require authentication.
app.UseStaticFiles();

//LogDashboard
//app.UseLogDashboard("/LogDashboard");

//hangfire
app.UseHangfireConfig(env);

// Swagger

if (isOpenSwagger)
{
    SwaggerSetup.Configure(app, env);
}


//serilog 记录请求的用户信息
app.UseSerilogConfig(env);

app.UseRouting();
app.UseCors(t => t.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
app.UseAuthentication();
app.UseAuthorization();


//Map MinimalAPI  routes
app.MapMasaMinimalAPIs();

//// 这里添加反伪造中间件
//app.UseAntiforgery();
app.MapControllers();

app.MapHub<UploadHub>("/UploadHub");
app.MapHealthChecks("/health");



#endregion





try
{
    #region 运行环境 部署平台

    Log.Logger.Warning($"当前环境：{enviromentName}");
    Log.Logger.Warning($".NET 运行时版本：{Environment.Version}");

    if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
    {
        Log.Logger.Warning($"当前部署平台环境：windows");
    }
    else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
    {
        Log.Logger.Warning($"当前部署平台环境：linux");
    }
    else
    {
        Log.Logger.Warning($"当前部署平台环境：OSX  or FreeBSD");
    }

    Log.Logger.Warning($"ContentRootPath：{env.ContentRootPath}");


    string parentDirectory = Path.GetFullPath(Path.Combine(env.ContentRootPath, ".."));


    Log.Logger.Warning($"ContentRootPath——parentDirectory：{parentDirectory}");

    //Log.Logger.Warning($"ContentRootPath——GetParent：{Directory.GetParent(env.ContentRootPath).Parent.FullName}");
    //Log.Logger.Warning($"ContentRootPath——xx：{Path.GetDirectoryName(Path.GetDirectoryName(env.ContentRootPath))}");
    #endregion

    app.Run();


}
catch (Exception e)
{

    Log.Logger.Error(e.InnerException is null ? e.Message + e.StackTrace : e.InnerException?.Message + e.InnerException?.StackTrace);
}



