package com.zbf.system.utils;

/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved.
 */

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.lang3.StringUtils;

import java.nio.charset.StandardCharsets;

import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

/**
 * <aksk签名工具>
 *
 * @author b30012543
 * @version SIMSSpace, 2021年10月19日
 * @see [相关类/方法]
 * @since SIMSSpace V100R005C06
 */
public class SignTool {
    /**
     * <用akskid、ak、sk生成签名>
     *
     * @param akskId akskId
     * @param ak ak
     * @param sk sk
     * @return String signStr
     * @throws Exception e
     * @author b30012543
     */
    public static String generateSign(String akskId, String ak, String sk) throws Exception {
        if (checkParamEmpty(akskId, ak, sk)) {
            throw new IllegalArgumentException("Parameter error");
        }
        String timestamp = String.valueOf(System.currentTimeMillis());
        return sign(akskId, ak, sk, timestamp);
    }

    public static boolean verification(String akskId, String ak, String sk, String timestamp, String sign)
            throws Exception {
        if (checkParamEmpty(akskId, ak, sk) || StringUtils.isEmpty(sign)) {
            return false;
        }
        return sign.equals(sign(akskId, ak, sk, timestamp));
    }

    private static String sign(String akskId, String ak, String sk, String timestamp) throws Exception {
        String text = akskId + timestamp;
        String hmacStr = getHmac(text, sk);
        // if (StringUtils.isEmpty(hmacStr)) {
        //     throw new AkSkException("Generate sign failed.");
        // }
        String sign = String.join(",", new String[] {hmacStr, timestamp, ak});
        return Base64.encodeBase64String(sign.getBytes(StandardCharsets.UTF_8));
    }

    private static String getHmac(String text, String sk) throws Exception {
        if (StringUtils.isEmpty(text)) {
            return text;
        }
        return encodeHmacSHA256(text, sk);
    }

    /**
     * <用akskid、sk生成签名>
     *
     * @param data 加密内容
     * @param key 加密密钥
     * @return String 签名内容
     * @throws Exception e
     * @author b30012543
     */
    private static String encodeHmacSHA256(String data, String key) throws Exception {
        // 加密秘钥
        SecretKey secretKey = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
        Mac mac = Mac.getInstance(secretKey.getAlgorithm());
        mac.init(secretKey);
        // 加密
        byte[] message = mac.doFinal(data.getBytes(StandardCharsets.UTF_8));
        return Hex.encodeHexString(message, false);
    }

    private static boolean checkParamEmpty(String akskId, String ak, String sk) {
        return StringUtils.isEmpty(akskId) || StringUtils.isEmpty(ak) || StringUtils.isEmpty(sk);
    }
}
