using Autofac;
using Autofac.Extensions.DependencyInjection;
using Long.Common;
using Long.Core.Middleware;
using Long.Dapper;
using Long.Service;
using Long.Utils.Converter;
using Long.Utils.Filter;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.OpenApi.Models;
using System.Reflection;

var builder = WebApplication.CreateBuilder(args);

// 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(options =>
{
    options.SwaggerDoc("v1", new OpenApiInfo { Title = "Long API", Version = "v1" });

    //为 Swagger JSON and UI设置xml文档注释路径
    var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
    var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
    options.IncludeXmlComments(xmlPath);

    options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
    {
        Scheme = JwtBearerDefaults.AuthenticationScheme,
        BearerFormat = "JWT",
        In = ParameterLocation.Header,
        Name = "Authorization",
        Type = SecuritySchemeType.ApiKey,
        Description = "Bearer Token"
    });
    options.AddSecurityRequirement(new OpenApiSecurityRequirement
    {
        {
            new OpenApiSecurityScheme
            {
                Reference = new OpenApiReference
                {
                    Type = ReferenceType.SecurityScheme,
                    Id = "Bearer"
                }
            },
            Array.Empty<string>()
        }
    });
});

// 配置跨域访问
var origins = builder.Configuration.GetSection("Cors:Origins").GetChildren().Select(x => x.Value ?? "").ToArray();
builder.Services.AddCors(c =>
{
    c.AddPolicy("cors", policy =>
    {
        policy.AllowAnyHeader();
        policy.AllowAnyMethod();
        policy.AllowCredentials();
        policy.WithOrigins(origins ?? Array.Empty<string>());
    });
});

// 配置 ids
var authority = builder.Configuration["JWT:Authority"];
var scheme = "Bearer";
builder.Services.AddAuthentication(scheme).AddJwtBearer(scheme, options =>
{
    options.Authority = authority;
    options.RequireHttpsMetadata = false;
    options.Audience = "LongApi";
    options.TokenValidationParameters.ValidateIssuer = false;
});
builder.Services.AddAuthorization(options =>
{
    options.AddPolicy("GuestApi", policy =>
    {
        policy.RequireClaim("scope", IdsScope.GuestApi);
    });
    options.AddPolicy("UserApi", policy =>
    {
        policy.RequireAuthenticatedUser();
        policy.RequireClaim("scope", IdsScope.UserApi);
    });
    options.AddPolicy("AdminApi", policy =>
    {
        policy.RequireAuthenticatedUser();
        policy.RequireClaim("scope", IdsScope.AdminApi);
    });
});

// 配置 Cookie
builder.Services.Configure<CookiePolicyOptions>(options =>
{
    options.CheckConsentNeeded = context => true;
    options.MinimumSameSitePolicy = SameSiteMode.None;
});

// 配置其他
builder.Services.AddMvc(options => { options.Filters.Add<ApiExceptionFilter>(); })
    .AddControllersAsServices()
    .AddJsonOptions(opt =>
    {
        opt.JsonSerializerOptions.PropertyNamingPolicy = null;
        opt.JsonSerializerOptions.Converters.Add(new LongJsonConverter());
    });

// 配置自动注册服务
builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory()).ConfigureContainer<ContainerBuilder>(c =>
{
    c.RegisterModule(new ServiceModule());
});

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    DatabaseConfig.AppSettingsFileName = "appsettings.Development.json";
}

app.UseSwagger();
app.UseSwaggerUI();

app.UseCors("cors");

app.UseHttpsRedirection();

app.UseAuthentication();
app.UseAuthorization();

app.MapControllers();

// 全局错误捕获
app.UseLongExtensionMiddleware();

app.Run();
