using Atomx.Admin.Utils;
using Atomx.Common.Constant;
using Atomx.Common.Models;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using System.Text;

namespace Atomx.Admin.Extensions
{
    public static class AuthorizationExtension
    {
        /// <summary>
        /// 添加身份验证服务
        /// </summary>
        /// <param name="services"></param>
        /// <param name="Configuration"></param>
        public static void AddAuthorize(this IServiceCollection services, IConfiguration Configuration)
        {
            var jwtSetting = Configuration.GetSection("Authentication:JwtBearer").Get<JwtSetting>();
            if (jwtSetting == null)
            {
                throw new Exception("缺少配置信息");
            }
            services.AddSingleton(jwtSetting);

            //认证配置
            services.AddAuthentication()
                   .AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options =>
                   {
                       options.ClaimsIssuer = jwtSetting.Issuer;
                       options.TokenValidationParameters = new TokenValidationParameters
                       {
                           ValidateIssuer = true,
                           ValidateAudience = true,
                           ValidateLifetime = true,
                           ValidateIssuerSigningKey = true,
                           ValidAudience = jwtSetting.Audience,//Audience
                           ValidIssuer = jwtSetting.Issuer,
                           ClockSkew = TimeSpan.FromMinutes(Convert.ToDouble(jwtSetting.ClockSkew)),
                           IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSetting.SecurityKey))
                       };
                       options.Events = new JwtBearerEvents
                       {
                           OnChallenge = context =>
                           {
                               var absoluteUri = $"{context.Request.Scheme}://{context.Request.Host}{context.Request.Path}{context.Request.QueryString}";
                               context.HandleResponse();
                               context.Response.Redirect($"/account/login?returnUrl={Uri.EscapeDataString(absoluteUri)}");
                               return Task.CompletedTask;
                           },

                           OnAuthenticationFailed = context =>
                           {
                               //Token expired
                               if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
                               {
                                   context.Response.Headers.Append("Token-Expired", "true");
                               }
                               return Task.CompletedTask;
                           }
                       };
                   });

            services.AddAuthorization(options =>
            {
                // 基于角色的策略
                //options.AddPolicy("AdminOnly", policy =>
                //    policy.RequireRole("Administrator"));

                //options.AddPolicy("ManagerOrAdmin", policy =>
                //    policy.RequireRole("Administrator", "Manager"));

                // 基于权限的策略
                var allPermissions = Permissions.GetAllPermissions();
                foreach (var permission in allPermissions)
                {
                    options.AddPolicy(permission, policy => { policy.Requirements.Add(new PermissionRequirement(permission)); });
                }


                // 组合策略
                //options.AddPolicy("CanManageUsers", policy =>
                //{
                //    policy.RequireRole("Administrator", "UserManager");
                //    policy.Requirements.Add(new PermissionRequirement(PermissionConstants.Users.Edit));
                //});
            });
        }
    }
}
