package cn.quantgroup.customer.util;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;

import java.security.SignatureException;
import java.util.*;

/**
 * xyqb 加签验证工具类
 * @author Feng
 * @version 2017.12.22
 */
public class SignUtil {

	public static final String KA_API_KEY = "100011";

	private static final long MAX_RATIO = 0x258;// 十分钟 10 * 60

	private static Map<String, String> apiKeys = new HashMap<>();
	static {
		apiKeys.put(KA_API_KEY, "aukpaqy3za9lkjisdfaoqtdtxumrjqzm");

		apiKeys.put("xyqb", "cd6yFfEgI0t67JaOYtLxTqXvumfJbsZi");
		apiKeys.put("kefu", "iy4tv3sc6y7jaj8pxipsjb05afew6sgy");
	}

	public static void addKeys(String appid, String key) {
		apiKeys.put(appid, key);
	}

	/**
	 * 参数签名
	 * 
	 * @return map 所有参数 以及 sign
	 */
	public static Map<String, ?> sign(String appid, Map<String, ?> params) {
		Map<String, Object> map = new HashMap<String, Object>();
		map.putAll(params);
		map.put("app_id", appid);
		map.put("timestamp", String.valueOf(System.currentTimeMillis() / 1000));
		map.put("noncestr", RandomStringUtils.randomAlphanumeric(8));
		String sign = signParams(map, appid);
		map.put("sign", sign);
		return map;
	}

	/**
	 * 签名
	 * 
	 * @param map
	 * @return
	 */
	private static String signParams(Map<String, ?> map, String appid) {
		List<String> names = new ArrayList<String>(map.keySet());
		Collections.sort(names);
		StringBuffer buffer = new StringBuffer();
		for (String key : names) {
			buffer.append(key).append("=").append(map.get(key)).append("&");
		}
		buffer.append("security_code=").append(apiKeys.get(appid));
		String sign = DigestUtils.md5Hex(buffer.toString());
		return sign;
	}

	/**
	 * 验证签名
	 * 
	 * @param params
	 *            1、参数中必须包含 app_id 、timestamp、noncestr,sign
	 * @return
	 * @throws IllegalAccessException
	 */
	public static boolean checkSign(Map<String, ?> params) throws SignatureException {
		String pid = Objects.toString(params.get("app_id"), null);
		String noncestr = Objects.toString(params.get("noncestr"), null);
		String timestamp = Objects.toString(params.get("timestamp"), null);
		String sign = Objects.toString(params.get("sign"), null);
		if (StringUtils.isBlank(pid) || StringUtils.isBlank(noncestr) || StringUtils.isBlank(timestamp)
				|| StringUtils.isBlank(sign)) {
			throw new SignatureException("参数中必须包含 app_id 、timestamp、noncestr 、sign");
		}
		// 验证时间
        int int13Line83 = 13;
		if (timestamp.length() == int13Line83) {
			long ratio = System.currentTimeMillis() - Long.valueOf(timestamp);
            int int1000Line86 = 1000;
			if (ratio > (MAX_RATIO * int1000Line86)) {
				throw new SignatureException("request overdue ....");
			}
		} else {
			long ratio = (System.currentTimeMillis() / 1000) - Long.valueOf(timestamp);
			if (ratio > MAX_RATIO) {
				throw new SignatureException("request overdue ....");
			}
		}
		params.remove("sign");
		String signVal = signParams(params, pid);// 签名
		return StringUtils.equalsIgnoreCase(signVal,sign);
	}

}
