package fastweb.config;


import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.JwtParser;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.io.Encoders;
import io.jsonwebtoken.security.Keys;

import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;

/**
 * JWT工具类
 *
 * @author Gerry
 */
public class JwtUtil {

    public static final String USER_TOKEN = "USER_TOKEN:%s";
    public static final String TOKEN_AUTHORITIES = "TOKEN_AUTHORITIES:%s";

    private JwtUtil() {
    }

    /**
     * 密钥（至少32字节，后续可根据需求换成RSA加密）
     */
    private static final byte[] SECRET = "soscsoscsoscsoscsoscsoscsoscsosc".getBytes();
    /**
     * JWT失效时间(分)
     */
    public static final int EXP_TIME = 24 * 60;

    /**
     * 生成token
     *
     * @param payloadMap 负载信息
     * @return token
     */
    public static String genToken(Map<String, Object> payloadMap) {
        JwtBuilder jwtBuilder = Jwts.builder();
        // 设置失效时间
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MINUTE, EXP_TIME);
        jwtBuilder.setExpiration(calendar.getTime());
        // 设置载荷
        jwtBuilder.addClaims(payloadMap);
        jwtBuilder.base64UrlEncodeWith(Encoders.BASE64URL);
        // 设置签名
        jwtBuilder.signWith(Keys.hmacShaKeyFor(SECRET));
        return jwtBuilder.compact();
    }

    /**
     * 生成token
     *
     * @return token
     */
    public static String genToken() {
        Map<String, Object> payload = new HashMap<>();
        return genToken(payload);
    }

    /**
     * 验证token有效性
     *
     * @param token token
     * @return R
     */
    public static R valid(String token) {
        try {
            JwtParser jwtParser = Jwts.parser();
            // 设置时钟偏移
            jwtParser.setAllowedClockSkewSeconds(3 * 60);
            // 设置签名
            jwtParser.setSigningKey(SECRET);
            Map<String, Object> payload = jwtParser.parseClaimsJws(token).getBody();
            return R.ok(payload);
        } catch (Exception e) {
            return R.error(e.getMessage());
        }
    }

}
