using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Tokens;
using System;
using System.Security.Claims;
using System.Text;

namespace HRD.LDAPService.JWT
{
    public static class JwtMiddlewareExtensions
    {
        public static IApplicationBuilder UseJwtMiddleware(this IApplicationBuilder builder)
        {
            return builder.UseMiddleware<JwtMiddleware>();
        }

        public static void ConfigureJWT(this IServiceCollection services, JwtMiddlewareOptions options)
        {
            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }

            JwtTokenConfig.DeaktivateLDAP = options.DeaktivateLDAP; //if true => use login + pwd only

            JwtTokenConfig.Secret = options.Secret;
            JwtTokenConfig.Issuer = options.Issuer;
            JwtTokenConfig.Audience = options.Audience;
            JwtTokenConfig.JwtRoleList = options.JwtRoleList;
            JwtTokenConfig.ExpirationInMin = options.ExpirationInMin;
            JwtTokenConfig.AktivateAuthorizationFilter = options.AktivateAuthorizationFilter;
            JwtTokenConfig.AuthorizationFilterWhitelistPath = options.AuthorizationFilterWhitelistPath;
            JwtTokenConfig.AuthorizationFilterBlacklistPath = options.AuthorizationFilterBlacklistPath;

            //Authentication
            services.AddAuthentication(options =>
            {
                options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                options.DefaultSignInScheme = JwtBearerDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            })
                //JwtBearer
                .AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options =>
            {
                options.RequireHttpsMetadata = true;
                options.SaveToken = true;
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuer = true,
                    ValidIssuer = JwtTokenConfig.Issuer, //JWT-Site
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(JwtTokenConfig.Secret)),
                    ValidAudience = JwtTokenConfig.Audience,
                    ValidateAudience = true, //App-Site
                    ValidateLifetime = true,
                    ClockSkew = TimeSpan.FromMinutes(1),
                    NameClaimType = ClaimTypes.NameIdentifier
                };
            });

            //Authorization
            services.AddAuthorization(authopt =>
            {
                authopt.AddPolicy("UserMustHaveRole", polBuilder => polBuilder.RequireClaim(ClaimTypes.Role));
            });
        }
    }
}