using Hangfire;
using HealthChecks.UI.Client;
using JiShe.CollectBus.Common;
using JiShe.CollectBus.Host.Extensions;
using JiShe.CollectBus.Host.HealthChecks;
using JiShe.CollectBus.Host.Swaggers;
using JiShe.CollectBus.IoTDB.Options;
using JiShe.CollectBus.MongoDB;
using Microsoft.AspNetCore.Diagnostics.HealthChecks;
using Swashbuckle.AspNetCore.SwaggerUI;
using Volo.Abp;
using Volo.Abp.AspNetCore.Authentication.JwtBearer;
using Volo.Abp.AspNetCore.Serilog;
using Volo.Abp.Autofac;
using Volo.Abp.BackgroundWorkers.Hangfire;
using Volo.Abp.Caching.StackExchangeRedis;
using Volo.Abp.Modularity;
using Volo.Abp.Swashbuckle;
using Volo.Abp.Timing;

namespace JiShe.CollectBus.Host
{
    /// <summary>
    /// 
    /// </summary>
    [DependsOn(typeof(CollectBusHttpApiModule),
        typeof(AbpAutofacModule),
        typeof(AbpAspNetCoreAuthenticationJwtBearerModule),
        typeof(AbpAspNetCoreSerilogModule),
        typeof(AbpSwashbuckleModule),
        typeof(AbpTimingModule),
        typeof(CollectBusApplicationModule),
        typeof(CollectBusMongoDbModule),
        typeof(AbpCachingStackExchangeRedisModule),
        typeof(AbpBackgroundWorkersHangfireModule)
        )]
    public partial class CollectBusHostModule : AbpModule
    {
        /// <summary>
        /// ConfigureServices
        /// </summary>
        /// <param name="context"></param>
        public override void ConfigureServices(ServiceConfigurationContext context)
        {
            var configuration = context.Services.GetConfiguration();
            ConfigureCache(context);
            ConfigureSwaggerServices(context, configuration);
            ConfigureNetwork(context, configuration);
            ConfigureJwtAuthentication(context, configuration);
            ConfigureHangfire(context);
            ConfigureAuditLog(context);
            ConfigureCustom(context, configuration);
            ConfigureHealthChecks(context, configuration);
            Configure<AbpClockOptions>(options => { options.Kind = DateTimeKind.Local; });

            Configure<ServerApplicationOptions>(options =>
            {
                configuration.GetSection(nameof(ServerApplicationOptions)).Bind(options);
            });

        }


        /// <summary>
        /// OnApplicationInitialization
        /// </summary>
        /// <param name="context"></param>
        public override void OnApplicationInitialization(ApplicationInitializationContext context)
        {
            var app = context.GetApplicationBuilder();
            var configuration = context.GetConfiguration();
            var env = context.GetEnvironment();
            app.UseCorrelationId();
            app.UseStaticFiles();
            app.UseRouting();
            app.UseCors(CollectBusHostConst.DefaultCorsPolicyName);
            app.UseAuthentication();
            app.UseAuthorization();
            if (env.IsDevelopment())
            {
                app.UseSwagger();
                app.UseAbpSwaggerUI(options =>
                {
                    configuration.GetSection("SwaggerConfig").Get<List<SwaggerConfig>>()?.ForEach(group =>
                    {
                        options.SwaggerEndpoint($"/swagger/{group.GroupName}/swagger.json", group.Title); //分组显示
                    });
                    options.DocExpansion(DocExpansion.None);
                    options.DefaultModelsExpandDepth(-1);
                });
            }
            app.UseAuditing();
            app.UseAbpSerilogEnrichers();
            app.UseUnitOfWork();
            app.UseHangfireDashboard("/hangfire", new DashboardOptions
            {
                IgnoreAntiforgeryToken = true
            });
            app.UseConfiguredEndpoints(endpoints =>
            {
                if (!configuration.GetValue<bool>("HealthChecks:IsEnable")) return;
                endpoints.MapHealthChecks("/health", new HealthCheckOptions
                {
                    Predicate = _ => true,
                    ResponseWriter = HealthCheckResponse.Writer
                });
                endpoints.MapHealthChecksUI(options =>
                {
                    options.UIPath = "/health-ui";
                });
            });
        }
    }
}
