/*
 * Decompiled with CFR 0.152.
 * 
 * Could not load the following classes:
 *  javax.servlet.http.HttpServletRequest
 *  sun.misc.BASE64Encoder
 */
package com.ifugle.util.export;

import com.hst.framework.exception.ServiceException;
import com.ifugle.util.export.ClientAccess;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.TreeMap;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpServletRequest;
import sun.misc.BASE64Encoder;

public final class URLSignUtil {
    private static final String CHARSET_NAME_UTF8 = "UTF-8";
    private static final Charset CHARSET_DEFAULT = Charset.forName("UTF-8");
    private static final String ALGORITHM_HMACSHA1 = "HmacSHA1";
    private static final String HEADER_AUTHORIZATION = "Authorization";
    private static final String HEADER_DATE = "Date";

    public static String sign(String method, String date, String uri, Map<String, String> parameters, String clientSecret) throws Exception {
        return URLSignUtil.sign(method, date, uri, URLSignUtil.getSortedQuery(parameters), clientSecret);
    }

    public static String sign(String method, String date, String uri, String queryString, String clientSecret) throws Exception {
        StringBuilder sb = new StringBuilder();
        sb.append(method).append('\n').append(date).append('\n').append(uri).append('?').append(queryString == null ? "" : queryString);
        byte[] text = URLSignUtil.getBytes(sb.toString());
        SecretKeySpec secretKey = new SecretKeySpec(URLSignUtil.getBytes(clientSecret), ALGORITHM_HMACSHA1);
        Mac mac = Mac.getInstance(ALGORITHM_HMACSHA1);
        mac.init(secretKey);
        byte[] finalText = mac.doFinal(text);
        return URLSignUtil.base64Encode(finalText);
    }

    public static String sign(HttpServletRequest request, String clientSecret) throws Exception {
        String method = request.getMethod();
        String date = request.getHeader(HEADER_DATE);
        String uri = request.getRequestURI();
        String queryString = request.getQueryString();
        return URLSignUtil.sign(method, date, uri, queryString, clientSecret);
    }

    public static boolean check(HttpServletRequest request, ClientAccess clientAccess) throws Exception {
        String authorization = request.getHeader(HEADER_AUTHORIZATION);
        if (authorization != null && !authorization.isEmpty()) {
            String[] split = authorization.split(":");
            if (split.length < 2) {
                throw new RuntimeException("\u7b7e\u540d\u6570\u636e\u683c\u5f0f\u9519\u8bef\uff01");
            }
            String clientSecret = clientAccess.getClientSecret(split[0]);
            String signature = URLSignUtil.sign(request, clientSecret);
            return split[1].equals(signature);
        }
        throw new RuntimeException("\u7b7e\u540d\u6570\u636e\u4e0d\u80fd\u4e3a\u7a7a\uff01");
    }

    public static boolean check(HttpServletRequest request, final String onlyClientId, final String onlyClientSecret) throws Exception {
        return URLSignUtil.check(request, new ClientAccess(){

            @Override
            public String getClientSecret(String clientId) {
                if (onlyClientId.equals(clientId)) {
                    return onlyClientSecret;
                }
                throw new ServiceException("\u8bd5\u56fe\u4f7f\u7528\u65e0\u6548\u7684 client_id");
            }
        });
    }

    public static String getSortedQuery(Map<String, String> parameters) throws Exception {
        TreeMap<String, String> treeMap = new TreeMap<String, String>();
        treeMap.putAll(parameters);
        StringBuilder sb = new StringBuilder();
        for (String key : treeMap.keySet()) {
            String value = (String)treeMap.get(key);
            sb.append(key);
            sb.append('=');
            if (value != null && !value.isEmpty()) {
                sb.append(URLEncoder.encode(value, CHARSET_NAME_UTF8));
            }
            sb.append('&');
        }
        if (sb.length() > 0) {
            sb.setLength(sb.length() - 1);
        }
        return sb.toString();
    }

    public static String getDate() {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return format.format(new Date());
    }

    private static byte[] getBytes(String text) {
        return text == null ? null : text.getBytes(CHARSET_DEFAULT);
    }

    private static String base64Encode(byte[] bytes) {
        return new BASE64Encoder().encode(bytes);
    }
}
