// Copyright (c) 2018 Jon P Smith, GitHub: JonPSmith, web: http://www.thereformedprogrammer.net/
// Licensed under MIT license. See License.txt in the project root for license information.

using System.Security.Claims;
using Hotline.SeedData;
using IdentityModel;
using Microsoft.AspNetCore.Authorization;

namespace Hotline.Permissions
{
    //thanks to https://www.jerriepelser.com/blog/creating-dynamic-authorization-policies-aspnet-core/

    public class PermissionHandler : AuthorizationHandler<PermissionRequirement>
    {
        private readonly IPermissionManager _permissionManager;

        public PermissionHandler(IPermissionManager permissionManager)
        {
            _permissionManager = permissionManager;
        }

        protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, PermissionRequirement requirement)
        {
            //var permissionsClaim =
            //    context.User.Claims.SingleOrDefault(c => c.Type == PermissionConstants.PackedPermissionClaimType);
            //// If user does not have the scope claim, get out of here
            //if (permissionsClaim == null)
            //    return Task.CompletedTask;

            //if (permissionsClaim.Value.ThisPermissionIsAllowed(requirement.PermissionName))
            //    context.Succeed(requirement);

            var scops = context.User.Claims.Where(d => d.Type == JwtClaimTypes.Scope).Select(d => d.Value).ToList();
            if (scops.Any(d => d == "hotline_api"))
            {
                var roles = context.User.Claims.Where(d => d.Type == ClaimTypes.Role).Select(d => d.Value).ToList();
                if (roles.Exists(d => d == RoleSeedData.AdminRole))
                {
                    context.Succeed(requirement);
                }
                else
                {
                    var permissions = _permissionManager.RolesToPermissions(roles);
                    if (permissions.Any(d => requirement.PermissionName == d))
                        context.Succeed(requirement);
                }
            }

            return Task.CompletedTask;
        }
    }
}