using Autofac;
using Autofac.Extensions.DependencyInjection;
using AutoMapper.EquivalencyExpression;
using FellowOakDicom;
using FellowOakDicom.Imaging;
using FellowOakDicom.Imaging.NativeCodec;
using FellowOakDicom.Network;
using IRaCIS.Core.Infra.EFCore;
using IRaCIS.Core.SCP;
using IRaCIS.Core.SCP.Filter;
using IRaCIS.Core.SCP.Service;
using MassTransit;
using MassTransit.NewIdProviders;
using Microsoft.AspNetCore.HttpOverrides;
using Microsoft.Extensions.DependencyInjection;
using Panda.DynamicWebApi;
using Serilog;
using Serilog.Events;
using System.Runtime.InteropServices;


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

var enviromentName = config["ASPNETCORE_ENVIRONMENT"];

var builder = WebApplication.CreateBuilder(new WebApplicationOptions
{
    EnvironmentName = enviromentName
});

#region 兼容windows 服务命令行的方式

int urlsIndex = Array.FindIndex(args, arg => arg != null && arg.StartsWith("--port"));

if (urlsIndex > -1)
{
    var port = args[urlsIndex].Substring("--port=".Length);
    Console.WriteLine(port);
    builder.WebHost.UseUrls($"http://0.0.0.0:{port}");
}

#endregion

#region 主机配置

NewId.SetProcessIdProvider(new CurrentProcessIdProvider());

builder.Configuration.AddJsonFile("appsettings.json", false, true)
                     .AddJsonFile($"appsettings.{enviromentName}.json", false, true);
builder.Host
            .UseServiceProviderFactory(new AutofacServiceProviderFactory())
            .ConfigureContainer<ContainerBuilder>(containerBuilder =>
            {
                containerBuilder.RegisterModule<AutofacModuleSetup>();
            })
            .UseSerilog();
#endregion

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

//健康检查
builder.Services.AddHealthChecks();

//本地化
builder.Services.AddJsonLocalization(options => options.ResourcesPath = "Resources");


// 异常、参数统一验证过滤器、Json序列化配置、字符串参数绑型统一Trim()
builder.Services.AddControllers(options =>
{
    options.Filters.Add<ModelActionFilter>();
    options.Filters.Add<ProjectExceptionFilter>();
    options.Filters.Add<UnitOfWorkFilter>();


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


builder.Services.AddOptions().Configure<AliyunOSSOptions>(_configuration.GetSection("AliyunOSS"));
builder.Services.AddOptions().Configure<ObjectStoreServiceOptions>(_configuration.GetSection("ObjectStoreService"));
builder.Services.AddOptions().Configure<DicomSCPServiceOption>(_configuration.GetSection("DicomSCPServiceConfig"));


//动态WebApi + UnifiedApiResultFilter  省掉控制器代码
//动态webApi     目前存在的唯一小坑是生成api上服务上的动态代理AOP失效    间接掉用不影响
builder.Services
           .AddDynamicWebApi(dynamicWebApiOption =>
            {
                //默认是 api
                dynamicWebApiOption.DefaultApiPrefix = "";
                //首字母小写
                dynamicWebApiOption.GetRestFulActionName = (actionName) => char.ToLower(actionName[0]) + actionName.Substring(1);
                //删除 Service后缀
                dynamicWebApiOption.RemoveControllerPostfixes.Add("Service");

            });

//AutoMapper
builder.Services.AddAutoMapper(automapper =>
{

    automapper.AddCollectionMappers();


}, typeof(BaseService).Assembly);

//EF ORM  QueryWithNoLock
builder.Services.AddEFSetup(_configuration);

builder.Services.AddMediator(cfg =>
{

});


//转发头设置  获取真实IP 
builder.Services.Configure<ForwardedHeadersOptions>(options =>
{
    options.ForwardedHeaders =
        ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
});

//Dicom影像渲染图片  跨平台
//builder.Services.AddDicomSetup();
new DicomSetupBuilder()
       .RegisterServices(s =>
            s.AddFellowOakDicom()
              .AddTranscoderManager<NativeTranscoderManager>()
              //.AddTranscoderManager<FellowOakDicom.Imaging.NativeCodec.NativeTranscoderManager>()
              .AddImageManager<ImageSharpImageManager>())
       .SkipValidation()
       .Build();



#endregion

// Add services to the container.

builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

// Configure the HTTP request pipeline.
//if (app.Environment.IsDevelopment())
//{
app.UseSwagger();
app.UseSwaggerUI();
//}

app.UseAuthorization();

app.MapControllers();

#region 日志

//Log.Logger = new LoggerConfiguration()
//                 .MinimumLevel.Information()
//                 .MinimumLevel.Override("Microsoft", LogEventLevel.Information)
//                 // Filter out ASP.NET Core infrastructre logs that are Information and below  日志太多了 一个请求 记录好几条
//                 .MinimumLevel.Override("Microsoft.AspNetCore", LogEventLevel.Warning)
//                 .MinimumLevel.Override("Hangfire", LogEventLevel.Warning)
//                 .MinimumLevel.Override("System.Net.Http.HttpClient.HttpReports", LogEventLevel.Warning)
//                 .Enrich.WithClientIp()

//                 .Enrich.FromLogContext()

//                 //控制台 方便调试 问题   我们显示记录日志 时 获取上下文的ip 和用户名 用户类型
//                 .WriteTo.Console(restrictedToMinimumLevel: LogEventLevel.Warning,
//                                  outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {SourceContext:l} || {Message} || {Exception} ||end {NewLine}")

//                 .WriteTo.File($"{AppContext.BaseDirectory}Serilogs/.log", rollingInterval: RollingInterval.Day,
//                                  outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {SourceContext:l} || {Message} || {Exception} ||end {NewLine}")
//                 .CreateLogger();

Log.Logger = new LoggerConfiguration()
     //.MinimumLevel.Information()
     .MinimumLevel.Override("Microsoft", LogEventLevel.Warning)
    .WriteTo.Console()
    .WriteTo.File($"{AppContext.BaseDirectory}Serilogs/.log", rollingInterval: RollingInterval.Day)
    .CreateLogger();

#endregion


#region 运行环境 部署平台

Log.Logger.Warning($"当前环境:{enviromentName}");

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");
}

#endregion

var logger = app.Services.GetService<Microsoft.Extensions.Logging.ILogger<Program>>();

var server = DicomServerFactory.Create<CStoreSCPService>(_configuration.GetSection("DicomSCPServiceConfig").GetValue<int>("ServerPort"), userState: app.Services,logger: logger);


app.Run();