package com.zfire.jiasm.syncdata.utils;

import io.jsonwebtoken.*;
import org.bouncycastle.util.encoders.Base64;

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

/**
 * jwt加密和解密的工具类
 * 创建者 科帮网
 * 创建时间 2017年11月24日
 */
public class JwtUtils {

    public static final int JWT_ERRCODE_NULL = 4000;            //Token不存在
    public static final int JWT_ERRCODE_EXPIRE = 4001;            //Token过期
    public static final int JWT_ERRCODE_FAIL = 4002;            //验证不通过
    public static final int JWT_ERRCODE_USERID_FAIL = 4002;            //验证不通过，用户ID不相符
    public static final String JWT_SECERT = "8677df7fc3a34e26a61c034d5ec8245d";            //密匙
    public static final long JWT_TTL = 60 * 60 * 10000;                                    //token有效时间


    /**
     * JWT创建秘钥
     *
     * @param id
     * @param subject
     * @param ttlMillis
     * @return
     */
    public static String createJWT(String id, String subject,String username, long ttlMillis) {
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);
        SecretKey secretKey = generalKey();
        JwtBuilder builder = Jwts.builder()
                .setId(id)
                .setSubject(subject)   // 用户账号
                .setIssuer("Runwise")     // 签发者
                .setIssuedAt(now)      // 签发时间
                .setAudience(username) // 用户名称
                // .claim("username",username) //用户账号
                .signWith(signatureAlgorithm, secretKey); // 签名算法以及密匙
        if (ttlMillis >= 0) {
            long expMillis = nowMillis + ttlMillis;
            Date expDate = new Date(expMillis);
            builder.setExpiration(expDate); // 过期时间
        }
        return builder.compact();
    }

    /**
     * 验证JWT
     *
     * @param jwtStr
     * @return
     */
    public static CheckResult validateJWT(String jwtStr) {
        CheckResult checkResult = new CheckResult();
        Claims claims = null;
        try {
            claims = parseJWT(jwtStr);
            if (claims == null) {
                checkResult.setSuccess(false);
                checkResult.setErrCode(JWT_ERRCODE_EXPIRE);
                return checkResult;
            }

            checkResult.setSuccess(true);
            checkResult.setClaims(claims);
        } catch (ExpiredJwtException e) {
            checkResult.setErrCode(JWT_ERRCODE_EXPIRE);
            checkResult.setSuccess(false);
        } catch (SignatureException e) {
            checkResult.setErrCode(JWT_ERRCODE_FAIL);
            checkResult.setSuccess(false);
        } catch (Exception e) {
            checkResult.setErrCode(JWT_ERRCODE_FAIL);
            checkResult.setSuccess(false);
        }
        return checkResult;
    }

    public static SecretKey generalKey() {
        byte[] encodedKey = Base64.decode(JWT_SECERT);
        SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
        return key;
    }

    /**
     * 解析JWT字符串
     *
     * @param jwt
     * @return
     * @throws Exception
     */
    public static Claims parseJWT(String jwt) throws Exception {

        SecretKey secretKey = generalKey();
        return Jwts.parser()
                .setSigningKey(secretKey)
                .parseClaimsJws(jwt)
                .getBody();
    }

    /**
     * 测试hong'l
     *
     * @param args
     * @throws InterruptedException
     */
    public static void main(String[] args) throws InterruptedException {
        //小明失效 10s
        String sc = createJWT("1442383293510397954", "huangyu","huangyu", 20*60*60*1000);
        System.out.println(sc);
        System.out.println(validateJWT(sc).getErrCode());
        System.out.println(validateJWT(sc).getClaims().getId());
        //Thread.sleep(3000);
        System.out.println(validateJWT(sc).getClaims());
        System.out.println(validateJWT(sc).getClaims().getId());
        System.out.println(validateJWT(sc).getClaims().getSubject());
    }
}
