using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Authorization;
using Microsoft.AspNetCore.Mvc.Filters;
using Performance.DtoModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;

namespace Performance.Api
{
    public class AuthenticationFilter : IAsyncAuthorizationFilter
    {
        private readonly ClaimService claimService;

        public AuthenticationFilter(ClaimService claimService)
        {
            this.claimService = claimService;
        }

        public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
        {
            if (context.Filters.Any(item => item is IAllowAnonymousFilter))
                return;

            var headers = context.HttpContext.Request.Headers;
            var authorization = headers["Authorization"];
            if (authorization.Count == 0 || string.IsNullOrEmpty(authorization.First()))
            {
                var response = new ApiResponse(ResponseType.TokenError, "Token无效");
                context.Result = new ObjectResult(response);
                return;
            }

            // 获取token字符串
            var token = authorization.First().Replace("Bearer ", "");
            // jwt是否被禁用
            if (!claimService.JwtUsable(token))
            {
                var response = new ApiResponse(ResponseType.TokenError, "当前请求Token已被禁用");
                context.Result = new ObjectResult(response);
                return;
            }

            // 调用此方法，根据token生成对应的"身份证持有人"
            var principal = await AuthenticateJwtToken(token);

            if (principal == null)
            {
                var response = new ApiResponse(ResponseType.TokenError, "Token无效");
                context.Result = new ObjectResult(response);
            }
            else
            {
                context.HttpContext.User = principal; // 设置身份验证的主体
            }
        }

        private Task<ClaimsPrincipal> AuthenticateJwtToken(string token)
        {
            if (ValidateToken(token, out Claim[] claims))
            {
                var infos = new ClaimsIdentity(claims, "Jwt");
                ClaimsPrincipal user = new ClaimsPrincipal(infos);
                return Task.FromResult(user);
            }
            return Task.FromResult<ClaimsPrincipal>(null);
        }

        private bool ValidateToken(string token, out Claim[] claims)
        {
            // 调用自定义的GetPrincipal获取Token的信息对象
            var simplePrinciple = JwtTokenHelper.GetPrincipal(token);
            // 获取主声明标识
            var identity = simplePrinciple?.Identity as ClaimsIdentity;

            claims = new Claim[] { };

            if (identity == null)
                return false;

            if (identity.Claims != null && identity.Claims.Any())
                claims = identity.Claims.ToArray();

            return identity.IsAuthenticated;
        }
    }

}
