using Autofac;
using IP2Region.Net.Abstractions;
using IP2Region.Net.XDB;
using IRaCIS.Core.Application.BackGroundJob;
using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Application.Service;
using IRaCIS.Core.Application.Service.BackGroundJob;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infra.EFCore;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.HttpOverrides;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Panda.DynamicWebApi;
using System;
using System.IO;
using System.Linq;
using System.Reflection;

namespace IRaCIS.Core.API;


public static class ServiceCollectionSetup
{
    public static void ConfigureServices(this IServiceCollection services, IConfiguration _configuration)
    {
        services.AddOptions().Configure<SystemEmailSendConfig>(_configuration.GetSection("SystemEmailSendConfig"));
        services.AddOptions().Configure<ServiceVerifyConfigOption>(_configuration.GetSection("BasicSystemConfig"));
        services.AddOptions().Configure<AliyunOSSOptions>(_configuration.GetSection("AliyunOSS"));
        services.AddOptions().Configure<ObjectStoreServiceOptions>(_configuration.GetSection("ObjectStoreService"));
        services.AddOptions().Configure<IRCEncreptOption>(_configuration.GetSection("EncrypteResponseConfig"));
        services.AddOptions().Configure<SystemPacsConfig>(_configuration.GetSection("SystemPacsConfig"));
        services.Configure<IRaCISBasicConfigOption>(_configuration.GetSection("IRaCISBasicConfig"));

        services.Configure<ServiceVerifyConfigOption>(_configuration.GetSection("BasicSystemConfig"));

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

        services.AddSingleton<IUserIdProvider, IRaCISUserIdProvider>();
        services.AddSingleton<ISearcher>(new Searcher(CachePolicy.Content, Path.Combine(AppContext.BaseDirectory, StaticData.Folder.Resources, "ip2region.xdb")));




        services.AddScoped(typeof(IRepository<>), typeof(Repository<>));
        services.AddScoped<IRepository, Repository>();

        services.AddScoped<IObtainTaskAutoCancelJob, ObtainTaskAutoCancelJob>();
        services.AddScoped<IIRaCISHangfireJob, IRaCISCHangfireJob>();

        // 注册以Service 结尾的服务
        services.Scan(scan => scan
            .FromAssemblies(typeof(BaseService).Assembly)
            .AddClasses(classes => classes.Where(t => t.Name.Contains("Service")))
            .AsImplementedInterfaces()
            .WithScopedLifetime());

        #region Register Controllers

        // Register all controllers in the assembly that implement IDynamicWebApi
        services.Scan(scan => scan
            .FromAssemblies(typeof(BaseService).Assembly)
            .AddClasses(classes => classes.AssignableTo<IDynamicWebApi>())
            .AsSelf()
            .WithScopedLifetime());

        #endregion


        // MediatR 进程内消息 事件解耦  从程序集中 注册命令和handler对应关系
        //builder.Services.AddMediatR(cfg => cfg.RegisterServicesFromAssemblyContaining<ConsistencyVerificationHandler>());



        #region  历史废弃配置
        //builder.Services.AddMemoryCache();
        ////上传限制 配置
        //builder.Services.Configure<FormOptions>(options =>
        //{
        //    options.MultipartBodyLengthLimit = int.MaxValue;
        //    options.ValueCountLimit = int.MaxValue;
        //    options.ValueLengthLimit = int.MaxValue;
        //});
        //IP 限流 可设置白名单 或者黑名单
        //services.AddIpPolicyRateLimitSetup(_configuration);
        // 用户类型 策略授权
        //services.AddAuthorizationPolicySetup(_configuration);
        #endregion
    }


}

#region Autofac 废弃
public class AutofacModuleSetup : Autofac.Module
{
    protected override void Load(ContainerBuilder containerBuilder)
    {

        #region  byzhouhang  20210917  此处注册泛型仓储 可以减少Domain层 和Infra.EFcore 两层 空的仓储接口定义和 仓储文件定义

        containerBuilder.RegisterGeneric(typeof(Repository<>))
            .As(typeof(IRepository<>)).InstancePerLifetimeScope();//注册泛型仓储

        containerBuilder.RegisterType<Repository>().As<IRepository>().InstancePerLifetimeScope();


        #endregion

        #region 指定控制器也由autofac 来进行实例获取 https://www.cnblogs.com/xwhqwer/p/15320838.html

        //获取所有控制器类型并使用属性注入
        containerBuilder.RegisterAssemblyTypes(typeof(BaseService).Assembly)
            .Where(type => typeof(IDynamicWebApi).IsAssignableFrom(type))
            .PropertiesAutowired();

        #endregion


        Assembly application = Assembly.LoadFrom(AppDomain.CurrentDomain.BaseDirectory + "IRaCIS.Core.Application.dll");
        containerBuilder.RegisterAssemblyTypes(application).Where(t => t.FullName.Contains("Service"))
            .PropertiesAutowired().AsImplementedInterfaces();

        //containerBuilder.RegisterType<HttpContextAccessor>().As<IHttpContextAccessor>().SingleInstance();
        //containerBuilder.RegisterType<UserInfo>().As<IUserInfo>().InstancePerLifetimeScope();


        //注册hangfire任务  依赖注入
        containerBuilder.RegisterType<ObtainTaskAutoCancelJob>().As<IObtainTaskAutoCancelJob>().InstancePerDependency();

    }
}
#endregion
