package com.skr.mdm.util;

import com.skr.mdm.authentication.TokenExpireException;
import com.skr.mdm.dto.LoginUserDTO;
import com.skr.mdm.enums.ResultCodeEnum;
import io.jsonwebtoken.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;

import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import java.security.Key;
import java.util.Date;

/**
 * @author nfq
 * @date 2020/7/16 10:36
 */
@Slf4j
public class JwtUserUtil {

    /**
     * jwt加密私钥
     */
    private static final String JWT_SECRET = "skr123456";

    private static Key KEY = null;
    private static final String LOGIN_USER_KEY = "LOGIN_USER_KEY";

    public static String getJwt(LoginUserDTO loginUserDTO) {
        String jwt = Jwts.builder()
                .setIssuedAt(new Date(loginUserDTO.getLoginTime()))
                .setExpiration(new Date(loginUserDTO.getTokenExpireTime()))
                .claim(LOGIN_USER_KEY, loginUserDTO.getToken())
                .signWith(SignatureAlgorithm.HS256, getKeyInstance()).compact();
        return jwt;
    }

    public static String getTokenByJwt(String jwt) {
        if (StringUtils.isBlank(jwt)) {
            return null;
        }
        try {
            Claims body = Jwts.parser().setSigningKey(getKeyInstance()).parseClaimsJws(jwt).getBody();
            String token = MapUtils.getString(body, LOGIN_USER_KEY);
            return token;
        } catch (ExpiredJwtException e) {
//            log.warn("jwt已过期");
            throw new TokenExpireException(ResultCodeEnum.TOKEN_EXPIRE.getCode(), ResultCodeEnum.TOKEN_EXPIRE.getMsg());
        } catch (UnsupportedJwtException e) {
            log.warn("不支持的JWT异常");
            throw new TokenExpireException(ResultCodeEnum.TOKEN_ILLEGAL.getCode(), ResultCodeEnum.TOKEN_ILLEGAL.getMsg());
        } catch (MalformedJwtException e) {
            log.warn("JWT格式错误异常");
            throw new TokenExpireException(ResultCodeEnum.TOKEN_ILLEGAL.getCode(), ResultCodeEnum.TOKEN_ILLEGAL.getMsg());
        } catch (SignatureException e) {
            log.warn("JWT签名异常");
            throw new TokenExpireException(ResultCodeEnum.TOKEN_ILLEGAL.getCode(), ResultCodeEnum.TOKEN_ILLEGAL.getMsg());
        } catch (IllegalArgumentException e) {
            log.warn("参数异常", e);
        }
        return null;
    }

    private static Key getKeyInstance() {
        if (KEY == null) {
            synchronized (JwtUserUtil.class) {
                // 双重锁
                if (KEY == null) {
                    byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(JWT_SECRET);
                    KEY = new SecretKeySpec(apiKeySecretBytes, SignatureAlgorithm.HS256.getJcaName());
                }
            }
        }
        return KEY;
    }
}
