package com.liquidnet.commons.lang.core;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.Date;
import java.util.Map;

@Data
@Component("jwtValidator")
@ConfigurationProperties(prefix = "jwt")
public class JwtValidator {
    private String ssoRedisKey = "adam:identity:sso:";
    private String msoRedisKey = "adam:identity:mso:";
    private String secret;
    // 分钟
    private Long expireTtl;
    private Long refreshTtl;
    private Long blacklistGracePeriod;

//    private static final long EXPIRE_TIME = 15 * 60 * 1000;
//    private static final String TOKEN_SECRET = "qZHglvNP0n0aOOckHiQXq5JMD468J4eG";

    private SecretKey secretKey;

    private SecretKey initSecretKey(String secret) {
        if (null == this.secretKey) {
            this.secretKey = new SecretKeySpec(secret.getBytes(), SignatureAlgorithm.HS256.getJcaName());
        }
        return this.secretKey;
    }

    /**
     * 用户登录成功后生成Jwt token
     * 使用Hs256算法
     *
     * @param claimsMap 保存在Payload（有效载荷）中的内容
     * @return token字符串
     */
    public String create(Map<String, Object> claimsMap) {
        long nowMillis = System.currentTimeMillis();
        long expMillis = System.currentTimeMillis() + expireTtl * 60000;

        JwtBuilder builder = Jwts.builder()
                .setClaims(claimsMap)
                .setIssuedAt(new Date(nowMillis))
                .setExpiration(new Date(expMillis))
                .signWith(SignatureAlgorithm.HS256, this.initSecretKey(this.secret));
        return builder.compact();
    }

    /**
     * 解析token，获取到Payload（有效载荷）中的内容，包括验证签名，判断是否过期
     *
     * @param token 令牌
     * @return
     */
    public Claims parse(String token) {
        return Jwts.parser()
                .setSigningKey(this.initSecretKey(this.secret))
                .parseClaimsJws(token).getBody();
    }
}
