package com.gic.haoban.manage.service.util;

import com.alibaba.fastjson.JSONObject;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.*;

public class SignatureGetterUtil {
    private String secret;

    public SignatureGetterUtil(String secret) {
        this.secret = secret;
    }

    public String get(String jsonStr) throws Exception {
        Map<String, Object> jsonDict = new HashMap<>();
        jsonDict = JSONObject.parseObject(jsonStr, jsonDict.getClass());
        List<String> paramList = new ArrayList<>();
        json2List(jsonDict, paramList);
        Collections.sort(paramList);
        return hmacSha256(list2String(paramList));
    }

    private String list2String(List<String> paramList) {
        String str = "";
        for (String param : paramList) {
            if (param.startsWith("sig=")) {
                continue; // ignore sig self
            }
            str += param + "&";
        }
        System.out.println(str);
        return str.substring(0, str.length() - 1);
    }

    private String hmacSha256(String data) throws Exception {
        Mac mac = Mac.getInstance("HmacSHA256");
        SecretKeySpec secretKeySpec = new SecretKeySpec(secret.getBytes("UTF-8"), "HmacSHA256");
        mac.init(secretKeySpec);
        byte[] signature = mac.doFinal(data.getBytes("UTF-8"));
        return Base64.getEncoder().encodeToString(signature);
    }

    private void json2List(Map<String, Object> jsonDict, List<String> paramList) {
        for (Map.Entry<String, Object> entry : jsonDict.entrySet()) {
            String k = entry.getKey();
            Object v = entry.getValue();
            if (v instanceof List) {
                for (Object item : (List<?>) v) {
                    json2List((Map<String, Object>) item, paramList);
                }
            } else {
                paramList.add(k + "=" + v);
            }
        }
    }
    /**
     * 模拟生成随机 nonce 字符串
     *
     * @return 随机字符串
     */
    public String genNonce() {
        return bytesToHex(Long.toString(System.nanoTime()).getBytes(StandardCharsets.UTF_8));
    }
    private String bytesToHex(final byte[] hash) {
        Formatter formatter = new Formatter();
        for (byte b : hash) {
            formatter.format("%02x", b);
        }
        String result = formatter.toString();
        formatter.close();
        return result;
    }

}
