using Microsoft.IdentityModel.Tokens;
using System.Security.Claims;

namespace Lactose.Utils;

public class TokenBuilder {

    SigningCredentials? credentials;
    int                 expireTime;
    ClaimsIdentity?     claims;

    public TokenBuilder(SigningCredentials? signingCredentials = null, int expireTime = 10) {
        this.credentials = signingCredentials;
        this.expireTime  = expireTime;
    }

    public TokenBuilder ExpireTime(int minutes) {
        expireTime = minutes;
        return this;
    }

    public TokenBuilder SigningCredentials(SigningCredentials signingCredentials) {
        credentials = signingCredentials;
        return this;
    }

    public TokenBuilder SetClaims(ClaimsIdentity identity) {
        claims = identity;
        return this;
    }

    private SecurityTokenDescriptor PrepareSecurityTokenDescriptor() {
        var descriptor = new SecurityTokenDescriptor {
            SigningCredentials = credentials,
            Expires = DateTime.UtcNow
        };
        if (expireTime>0) descriptor.Expires   = DateTime.UtcNow.AddMinutes(expireTime);
        if (claims != null) descriptor.Subject = claims;
        return descriptor;
    }

    public SecurityToken GenerateToken(SecurityTokenHandler handler) => GenerateToken(handler.CreateToken);


    public T GenerateToken<T>(Func<SecurityTokenDescriptor, T> handler) {
        T token = handler(PrepareSecurityTokenDescriptor());
        claims = null;
        return token;
    }
}