using JiShe.CollectBusEPO.HttpApi.Host.Swaggers;

namespace JiShe.CollectBusEPO;

public partial class CollectBusEPOHttpApiHostModule
{
    
    /// <summary>
    /// 配置JWT
    /// </summary>
    private void ConfigureJwtAuthentication(ServiceConfigurationContext context, IConfiguration configuration)
    {
        context.Services.AddAuthentication(options =>
            {
                options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            })
            .AddJwtBearer(options =>
            {
                options.TokenValidationParameters =
                    new TokenValidationParameters()
                    {
                        // 是否开启签名认证
                        ValidateIssuerSigningKey = true,
                        ValidateIssuer = true,
                        ValidateAudience = true,
                        ValidateLifetime = true,
                        ClockSkew = TimeSpan.Zero,
                        ValidIssuer = configuration["Jwt:Issuer"],
                        ValidAudience = configuration["Jwt:Audience"],
                        IssuerSigningKey =
                            new SymmetricSecurityKey(
                                Encoding.ASCII.GetBytes(configuration["Jwt:SecurityKey"]))
                    };

                options.Events = new JwtBearerEvents
                {
                    OnMessageReceived = currentContext =>
                    {
                        var path = currentContext.HttpContext.Request.Path;
                        if (path.StartsWithSegments("/login"))
                        {
                            return Task.CompletedTask;
                        }

                        var accessToken = string.Empty;
                        if (currentContext.HttpContext.Request.Headers.ContainsKey("Authorization"))
                        {
                            accessToken = currentContext.HttpContext.Request.Headers["Authorization"];
                            if (!string.IsNullOrWhiteSpace(accessToken))
                            {
                                accessToken = accessToken.Split(" ").LastOrDefault();
                            }
                        }

                        if (accessToken.IsNullOrWhiteSpace())
                        {
                            accessToken = currentContext.Request.Query["access_token"].FirstOrDefault();
                        }

                        if (accessToken.IsNullOrWhiteSpace())
                        {
                            accessToken = currentContext.Request.Cookies[@CollectBusEPOHttpApiHostConst.DefaultCookieName];
                        }

                        currentContext.Token = accessToken;
                        currentContext.Request.Headers.Remove("Authorization");
                        currentContext.Request.Headers.Add("Authorization", $"Bearer {accessToken}");

                        return Task.CompletedTask;
                    }
                };
            });
    }


    /// <summary>
    /// Redis缓存
    /// </summary>
    private void ConfigureCache(ServiceConfigurationContext context)
    {
        Configure<AbpDistributedCacheOptions>(
            options => { options.KeyPrefix = "MicroService:"; });
        var configuration = context.Services.GetConfiguration();
        var redis = ConnectionMultiplexer.Connect(configuration.GetValue<string>("Redis:Configuration"));
        context.Services
            .AddDataProtection()
            .PersistKeysToStackExchangeRedis(redis, "MicroService-Protection-Keys");
    }

    /// <summary>
    /// 配置Identity
    /// </summary>
    private void ConfigureIdentity(ServiceConfigurationContext context)
    {
        context.Services.Configure<IdentityOptions>(options => { options.Lockout = new LockoutOptions() { AllowedForNewUsers = false }; });
    }
 

    private void ConfigureSwaggerServices(ServiceConfigurationContext context, IConfiguration configuration)
    {
        context.Services.AddSwaggerGen(
            options =>
            {
                configuration.GetSection("SwaggerConfig").Get<List<SwaggerConfig>>().ForEach(group =>
                {
                    options.SwaggerDoc(group.GroupName,
                        new OpenApiInfo { Title = group.Title, Version = group.Version });
                });

                options.DocInclusionPredicate((docName, apiDes) =>
                {
                    if (docName == "Basic" && apiDes.GroupName.IsNullOrWhiteSpace()) return true;
                    return docName == apiDes.GroupName;
                });

                options.EnableAnnotations();
                options.DocumentFilter<HiddenAbpDefaultApiFilter>();
                options.SchemaFilter<EnumSchemaFilter>();
                var xmlPaths = Directory.GetFiles(AppContext.BaseDirectory, "*.xml")
                    .Where(a => a.EndsWith("Application.App.xml") ||
                                a.EndsWith("Application.Contracts.App.xml") ||
                                a.EndsWith("Application.xml") ||
                                a.EndsWith("Application.Contracts.xml") ||
                                a.EndsWith("HttpApi.xml") ||
                                a.EndsWith("HttpApi.Host.xml"))
                    .Distinct()
                    .ToList();
                foreach (var xml in xmlPaths) options.IncludeXmlComments(xml, true);
            });
    }


    
    /// <summary>
    /// 审计日志
    /// </summary>
    private void ConfigureAuditLog(ServiceConfigurationContext context)
    {
        Configure<AbpAuditingOptions>
        (
            options =>
            {
                options.IsEnabled = true;
                options.EntityHistorySelectors.AddAllEntities();
                options.ApplicationName = "JiShe.MicroService";
            }
        );

        Configure<AbpAspNetCoreAuditingOptions>(
            options =>
            {
                options.IgnoredUrls.Add("/AuditLogs/page");
                options.IgnoredUrls.Add("/hangfire/stats");
                options.IgnoredUrls.Add("/hangfire/recurring/trigger");
                options.IgnoredUrls.Add("/cap");
                options.IgnoredUrls.Add("/");
            });
    }

    //private void ConfigurationMultiTenancy()
    //{
    //    Configure<AbpMultiTenancyOptions>(options => { options.IsEnabled = MultiTenancyConsts.IsEnabled; });
    //}

    private void ConfigureCustom(ServiceConfigurationContext context, IConfiguration configuration)
    {
        context.Services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
        //context.Services.AddStorage(configuration);
    }
     
    /// <summary>
    /// 配置Serilog
    /// </summary>
    private void ConfigureSerilog(ServiceConfigurationContext context)
    {
        context.Services.AddSerilog();
    }
}