package psdi.app.iface.comm;

import io.jsonwebtoken.*;
import io.jsonwebtoken.impl.DefaultClaims;

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

/**
 * @author liuxq
 * @title
 * @description
 **/
public class AESUtil {
    //密钥明文I guess PeterPan was right,growing up's a waste of time.
    private static final String SECRET_CLEARTEXT = "liuxingq";
    //过期时间默认为半小时后过期
//    private static final long EXPIRATION_TIME = 1000 * 60 * 30L;
    private static final long EXPIRATION_TIME = 1000 * 60 * 120L;

    public static SecretKey getSecretKey() {
        //以Base64编码获取到明文密钥的字节  以该数组生成一个AES算法的的密钥
        return new SecretKeySpec(Base64.getDecoder().decode(SECRET_CLEARTEXT) ,  "AES");
    }

    public static String getUUID() {
        return UUID.randomUUID().toString().replaceAll("-" , "");
    }

    /**
     * 加密
     * @param str
     * @return
     */
    public static String createCiphertext(String str) {
        return getJwtBuilder(str).compact();
    }

    public static String createCiphertext(String str , long mills) {
        return getJwtBuilder(str , mills).compact();
    }

    public static JwtBuilder getJwtBuilder(String str) {
        if(str == null)
            throw new RuntimeException("实体数据为空");
        //获取到AES算法的密钥
        long nowMills = System.currentTimeMillis();
        DefaultClaims defaultClaims = new DefaultClaims();
        defaultClaims.put("msg" , str);
        return Jwts.builder()
                .setId(getUUID())          //唯一的ID
                .setSubject("data")       // 数据
                .setIssuer("liuxingq")     // 签发者
                .setClaims(defaultClaims)  //数据
                .setIssuedAt(new Date(nowMills))      // 签发时间设置为当前
                .signWith(SignatureAlgorithm.HS256, getSecretKey()) //使用HS256对称加密算法签名, 第二个参数为秘钥
                .setExpiration(new Date(nowMills + EXPIRATION_TIME));//设置为超时时间
    }

    public static JwtBuilder getJwtBuilder(String str , long mills) {
        if(str == null)
            throw new RuntimeException("实体数据为空");
        //获取到AES算法的密钥
        long nowMills = System.currentTimeMillis();
        DefaultClaims defaultClaims = new DefaultClaims();
        defaultClaims.put("msg" , str);
        return Jwts.builder()//一个构造器 下面为必要属性的设置
                .setId(getUUID())           //唯一的ID
                .setSubject("data")        //主题为token
                .setIssuer("liuxingq")      // 签发者
                .setClaims(defaultClaims)   //数据存放
                .setIssuedAt(new Date(nowMills))      // 签发时间设置为当前
                .signWith(SignatureAlgorithm.HS256, getSecretKey()) //使用HS256对称加密算法签名, 第二个参数为秘钥
                .setExpiration(new Date(nowMills + mills));//设置过期时间
    }

    /**
     *
     * 解密
     */
/*    public static String getPlaintext(String str)
            throws UnsupportedJwtException ,//不支持的格式异常
            MalformedJwtException ,//平台jwt异常
            SignatureException,//签名异常
            ExpiredJwtException,//超时异常
            IllegalArgumentException { //非法参数异常
        return Jwts.parser()//token的语法分析器
                .setSigningKey(getSecretKey())//设置签名验证所用的密钥
                .parseClaimsJws(str)//处理token
                .getBody()//获取存入的token里的所有信息
                .get("msg").toString();//获取claims里面存放的msg数据
    }*/

    /**
     *
     * 解密
     */
    public static String getPlaintext(String str)
            throws UnsupportedJwtException ,//不支持的格式异常
            MalformedJwtException ,//平台jwt异常
            SignatureException,//签名异常
            ExpiredJwtException,//超时异常
            IllegalArgumentException { //非法参数异常
        String text = "";
        try {
            text = Jwts.parser()//token的语法分析器
                    .setSigningKey(getSecretKey())//设置签名验证所用的密钥
                    .parseClaimsJws(str)//处理token
                    .getBody()//获取存入的token里的所有信息
                    .get("msg").toString();//获取claims里面存放的msg数据
        } catch (ExpiredJwtException e1) {
            text = "Error: Expired";
        } catch (SignatureException e2) {
            text = "Error: Signature error";
        } catch (IllegalArgumentException e3) {
            text = "Error: Argument error";
        } catch (Exception e4) {
            text = "Error: Other error";
        }
        return text;
    }

        public static void main(String[] args) {
            //加密
            String jiami = createCiphertext("0113932-OA2EAMIFACE");
            System.out.println("jiami="+jiami);
            //解密
            String jiemi = AESUtil.getPlaintext(jiami);
            System.out.println("jiemi="+jiemi);
        }

}
