package dev.dinauer.maven;

import dev.dinauer.maven.maven.token.TokenEntity;
import dev.dinauer.maven.maven.token.TokenRepo;
import io.quarkus.elytron.security.common.BcryptUtil;
import io.quarkus.security.AuthenticationFailedException;
import io.quarkus.security.identity.AuthenticationRequestContext;
import io.quarkus.security.identity.IdentityProvider;
import io.quarkus.security.identity.SecurityIdentity;
import io.quarkus.security.identity.request.TokenAuthenticationRequest;
import io.quarkus.security.identity.request.UsernamePasswordAuthenticationRequest;
import io.quarkus.security.runtime.QuarkusPrincipal;
import io.quarkus.security.runtime.QuarkusSecurityIdentity;
import io.smallrye.mutiny.Uni;
import io.smallrye.mutiny.infrastructure.Infrastructure;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.context.control.ActivateRequestContext;
import jakarta.inject.Inject;

import java.time.LocalDate;
import java.util.Base64;

@ApplicationScoped
public class TokenIdentityProvider implements IdentityProvider<UsernamePasswordAuthenticationRequest>
{
    @Inject
    TokenRepo tokenRepo;

    @Override
    public Class<UsernamePasswordAuthenticationRequest> getRequestType()
    {
        return UsernamePasswordAuthenticationRequest.class;
    }

    @Override
    @ActivateRequestContext
    public Uni<SecurityIdentity> authenticate(UsernamePasswordAuthenticationRequest request, AuthenticationRequestContext authenticationRequestContext)
    {
        return Uni.createFrom().item(() -> {
            String username = request.getUsername();
            String password = new String(request.getPassword().getPassword());
            for (TokenEntity token : tokenRepo.findByUserId(username))
            {
                if (BcryptUtil.matches(password, token.getToken()))
                {
                    LocalDate now = LocalDate.now();
                    if (!now.isAfter(token.getExpiresAt()))
                    {
                        return (SecurityIdentity) QuarkusSecurityIdentity.builder().setPrincipal(new QuarkusPrincipal(token.getUserId())).build();
                    }
                }
            }
            throw new AuthenticationFailedException();
        }).runSubscriptionOn(Infrastructure.getDefaultWorkerPool());
    }
}
