package pwc.taxtech.atms.common.util;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.TreeMap;

public class SignatureUtil {
    private static final Logger LOGGER = LoggerFactory.getLogger(SignatureUtil.class);
    public static final String SIGN_NONCE_STR = "nonceStr"; //随机数
    public static final String SIGN_TIMESTAMP = "timestamp"; //时间戳
    public static final String SIGN_APP_Id = "appId"; //应用Id
    public static final String SIGN_SIGNATURE = "signature"; //生成的签名
    public static final String SIGN_API = "api"; //接口地址
    public static final String SIGN_API_TOKEN = "apiToken"; //密钥
    public static final String AND = "=";
    public static final String SPLIT = "&";
    public static final int TIME_RANGE = 120;//2分钟

    /**
     * 生成签名
     *
     * @param key       密钥
     * @param api       请求地址
     * @param nonceStr  随机字符串
     * @param timestamp 时间戳
     * @return string
     */
    public static String generate(String key, String api, String nonceStr, String timestamp) {
        TreeMap<String, String> paramMap = new TreeMap<>();
        paramMap.put(SIGN_API_TOKEN, key);
        paramMap.put(SIGN_API, api);
        paramMap.put(SIGN_NONCE_STR, nonceStr);
        paramMap.put(SIGN_TIMESTAMP, timestamp);
        StringBuilder sb = new StringBuilder();
        paramMap.forEach((k, v) -> {
            sb.append(k).append(AND).append(v).append(SPLIT);
        });
        String tmp = sb.substring(0, sb.length() - 1);
        return DigestUtils.sha1Hex(tmp);
    }

    /**
     * 校验签名
     *
     * @param key       密钥
     * @param api       请求地址
     * @param nonceStr  随机字符串
     * @param timestamp 时间戳
     * @param signature 接收的签名
     * @return boolean
     */
    public static boolean validate(String key, String api, String nonceStr, String timestamp, String signature) {
        try {
            if (StringUtils.isAnyBlank(key, api, nonceStr, timestamp, signature)) {
                return false;
            }
            int now = (int) (System.currentTimeMillis() / 1000);
            int time = Integer.valueOf(timestamp);
            if (now - time <= TIME_RANGE) {
                return StringUtils.equals(signature, generate(key, api, nonceStr, timestamp));
            }
        } catch (Exception e) {
            LOGGER.error("invalid signature.", e);
        }
        return false;
    }

}