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 主机配置

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


builder.Services.AddFellowOakDicom().AddTranscoderManager<NativeTranscoderManager>()
              //.AddTranscoderManager<FellowOakDicom.Imaging.NativeCodec.NativeTranscoderManager>()
              .AddImageManager<ImageSharpImageManager>();



#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.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

DicomSetupBuilder.UseServiceProvider(app.Services);

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();