package com.artfess.manage.utils;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.security.MessageDigest;
import java.security.SecureRandom;
import java.util.Arrays;
import java.util.Map;
import java.util.Random;
import java.util.Set;

public class SignUtils {
    public static final String SIGN_FIELD = "sign";
    public static final String SYMBOLS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
    public static final Random RANDOM = new SecureRandom();

    public static boolean isSignatureValid(Map<String, String> data, String key, SignType signType) throws Exception {
        if (!data.containsKey("sign")) {
            return false;
        }
        String sign = (String) data.get("sign");
        return generateSignature(data, key, signType).equalsIgnoreCase(sign);
    }

    public static String generateSignature(Map<String, String> data, String key) throws Exception {
        return generateSignature(data, key, SignType.MD5);
    }

    public static String generateSignature(Map<String, String> data, String key, SignType signType) throws Exception {
        Set<String> keySet = data.keySet();
        String[] keyArray = (String[]) keySet.toArray(new String[keySet.size()]);
        Arrays.sort(keyArray);
        StringBuilder sb = new StringBuilder();
        for (String k : keyArray) {
            if (!k.equals("sign")) {
                String value = String.valueOf(data.get(k));
                if (value.trim().length() > 0) {
                    sb.append(k).append("=").append(value.trim()).append("&");
                }
            }
        }
        sb.append("key=").append(key);
        System.out.println("签名内容" + sb.toString());
        if (SignType.MD5.equals(signType)) {
            return MD5(sb.toString()).toUpperCase();
        }
        if (SignType.HMACSHA256.equals(signType)) {
            String sign = HMACSHA256(sb.toString(), key);
            System.out.println("签名结果" + sign);
            return sign;
        }
        throw new Exception(String.format("Invalid sign_type: %s", new Object[]{signType}));
    }

//    public static String generateNonceStr() {
//        nonceChars = new char[32];
//        for (int index = 0; index < nonceChars.length; index++) {
//            nonceChars[index] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".charAt(RANDOM.nextInt("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".length()));
//        }
//        return new String(nonceChars);
//    }

    public static String MD5(String data) throws Exception {
        MessageDigest md = MessageDigest.getInstance("MD5");
        byte[] array = md.digest(data.getBytes("UTF-8"));
        StringBuilder sb = new StringBuilder();
        for (byte item : array) {
            sb.append(Integer.toHexString(item & 0xFF | 0x100).substring(1, 3));
        }
        return sb.toString().toUpperCase();
    }

    public static String HMACSHA256(String data, String key) throws Exception {
        Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
        SecretKeySpec secret_key = new SecretKeySpec(key.getBytes("UTF-8"), "HmacSHA256");
        sha256_HMAC.init(secret_key);
        byte[] array = sha256_HMAC.doFinal(data.getBytes("UTF-8"));
        StringBuilder sb = new StringBuilder();
        for (byte item : array) {
            sb.append(Integer.toHexString(item & 0xFF | 0x100).substring(1, 3));
        }
        return sb.toString().toUpperCase();
    }

    public static long getCurrentTimestamp() {
        return System.currentTimeMillis() / 1000L;
    }

    public static long getCurrentTimestampMs() {
        return System.currentTimeMillis();
    }

    public enum SignType

    {
        MD5, HMACSHA256;
    }
}
