using DFS.Core.Mvc;
using DFS.Core.Mvc.Authorize;
using DFS.Core.Mvc.Filters;
using DFS.Core.Mvc.Jwt;
using DFS.Core.Utils;
using DFS.Core.Utily;
using FuelServer.Core;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.IdentityModel.Tokens;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System.Text;
using System.Xml.Linq;

namespace Fuel.PaymentServer.MicServer
{

   

    public static class WebAppliactionExtend
    {
       

        /// <summary>
        /// 添加服务注入
        /// </summary>
        /// <param name="services"></param>
        /// <param name="environmentName"></param>
        /// <returns></returns>
        public static IServiceCollection AddMicService(this IServiceCollection services, IWebHostEnvironment environmentName)
        {
            services.AddSingleton(new Appsettings(environmentName.ContentRootPath, environmentName.EnvironmentName));
            //services.AddJwtAuth();
            services.AddHealthChecks();
            SecurityKey securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(ConstKey.JwtKey));    // 注意：这里的key不能低于16位
            services.AddAuthentication("Bearer")        // 注入认证服务，认证类型：Bearer
                .AddJwtBearer(o =>        // 注入 Jwt Bearer认证 服务，对其进行配置
                {
                    // 主要是这里：
                    o.Events = new JwtBearerEvents()
                    {
                        OnMessageReceived = context => {
                            context.Token = context.Request.Query["access_token"];
                            return Task.CompletedTask;
                        }
                    };

                    // 对 jwt 进行配置
                    o.TokenValidationParameters = new TokenValidationParameters()        // 对Token的认证是哪些参数，这里设置
                    {
                        ValidateIssuerSigningKey = true, 
                        IssuerSigningKey = securityKey,     
                        ValidateIssuer = true, 
                        ValidIssuer = ConstKey.JwtIssuer, 
                        ValidateAudience = true,     
                        ValidAudience = ConstKey.JwtAudience,       
                        RequireExpirationTime = true,       
                        ValidateLifetime = true,        
                    };
                });


            // 服务注入
            services.AddAuthorization(o => {
                //内部账户认证
                o.AddPolicy("IntClient",o => {
                    o.RequireRole("IntClient").Build();
                });

                //内部服务认证
                o.AddPolicy("IntServer", o => {
                    o.RequireRole("IntServer").Build();
                });

                //自定义授权(后台权限验证)
                o.AddPolicy("Admin", o => {
                    var myAdminRequirement = new DfsAuthorizationRequirement("DfsAuthorizationRequirement");    // 可以传递参数
                    o.Requirements.Add(myAdminRequirement);        
                });
            });

            services.AddSingleton<IAuthorizationHandler, DFSAuthorizationHandler>();

            services.AddControllers(options =>
            {
                options.Filters.Add(typeof(ValidationActionFilter));
                options.Filters.Add(typeof(StandardResultFilter));
                options.Filters.Add(typeof(ServiceExceptionFilter));
            })
            .AddNewtonsoftJson(options =>//全局配置Json序列化处理
            {
                //忽略循环引用
                options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
                //不使用驼峰样式的key
                options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
            }).AddJsonOptions(options => options.JsonSerializerOptions.Converters.Add(new DatetimeJsonConverter()));

            if (services.All(u => u.ServiceType != typeof(IHttpContextAccessor)))
            {
                services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
            }
            return services;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="application"></param>
        /// <returns></returns>
        public static WebApplication UseDFSServer(this WebApplication application)
        {
            application.UseCors(p => p.AllowCredentials());
            return application;
        }
    }
}
