﻿using AspNet.Security.OpenIdConnect.Extensions;
using AspNet.Security.OpenIdConnect.Server;
using Microsoft.AspNet.Authentication;
using Microsoft.AspNet.Http.Authentication;
using Microsoft.AspNet.Identity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using TimePunchAPI.Models;
using TimePunchAPI.Services;
using Microsoft.Extensions.DependencyInjection;

    namespace TimePunchAPI.Infrastructure
{
    public sealed class AuthenticationProvider : OpenIdConnectServerProvider
    {
        
        public override Task ValidateClientAuthentication(
            ValidateClientAuthenticationContext context)
        {
            // Since there's only one application and since it's a public client
            // (i.e a client that cannot keep its credentials private), call Skipped()
            // to inform the server the request should be accepted without 
            // enforcing client authentication.
            context.Skipped();

            return Task.FromResult(0);
        }

        public override async Task GrantResourceOwnerCredentials(
            GrantResourceOwnerCredentialsContext context)
        {
            // Validate the credentials here (e.g using ASP.NET Identity).
            // You can call Rejected() with an error code/description to reject
            // the request and return a message to the caller.

            var authenticationService = context.HttpContext.RequestServices.GetService<AuthenticationService>();
            var validatedId = await authenticationService.GetValidId(context.UserName, context.Password);
            if (validatedId == -1)
            {
                context.Rejected(OpenIdConnectConstants.Errors.InvalidGrant, "Not good enough");
                return;
            }
            else
            {

                var identity =
                    new ClaimsIdentity(OpenIdConnectServerDefaults.AuthenticationScheme);
                identity.AddClaim(ClaimTypes.NameIdentifier, context.UserName, "token id_token");
                identity.AddClaim(ClaimTypes.Name, context.UserName, "token id_token");
                identity.AddClaim("Id", validatedId.ToString(), "token id_token");

                var ticket = new AuthenticationTicket(
                    new ClaimsPrincipal(identity),
                    new AuthenticationProperties(),
                    context.Options.AuthenticationScheme);

                // Call SetResources with the list of resource servers
                // the access token should be issued for.
                ticket.SetResources(new[] { "resource_server_1" });

                // Call SetScopes with the list of scopes you want to grant
                // (specify offline_access to issue a refresh token).
                ticket.SetScopes(new[] { "profile", "offline_access" });

                context.Validated(ticket);
            }
            //return Task.FromResult<object>(null);
        }
    }
}