package com.docus.server.collect.web.utils;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Slf4j
public class UrlEncode {
    public static final boolean JDK_VERSION_IS_8 = true;
    /**
     * 将 String 转为 map
     *
     * eg:sex=man&name=zhangsan&age=20
     * @param queryStr
     *            aa=11&bb=22&cc=33
     * @return
     */
    public static Map<String, String> getUrlParams(String queryStr) {
        if (JDK_VERSION_IS_8) {
            return Stream.of(queryStr.split("&")).map(str -> str.split("=")).collect(Collectors.toMap(arr -> arr[0], arr -> (arr.length>1 ? arr[1] : "")));
        } else {
            Map<String, String> map = new HashMap<>(20);
            if ("".equals(queryStr) || null == queryStr) {
                return map;
            }
            String[] params = queryStr.split("&");
            for (int i = 0; i < params.length; i++) {
                String[] p = params[i].split("=");
                if (p.length == 2) {
                    map.put(p[0], p[1]);
                }
            }
            return map;
        }
    }

    /**
     * 说明
     * @RequestParam 只能用-Content-Type: 为 application/x-www-form-urlencoded，数据只能request.getParameter()
     * @RequestBody  只能用-Content-Type: 为 application/json,数据只能request.getInputStream转成字符串，在转成对应的类型
     */
    public static Map<String, String> getUrlParams(HttpServletRequest request) {
        try {
            String params = IOUtils.toString(request.getInputStream(), "UTF-8");
            try {
                //url 解码
                params = URLDecoder.decode(params, "UTF-8");
            } catch (UnsupportedEncodingException e) {
                log.error(e.getMessage());
            }
            if (params != null && params.trim().length() != 0) {
                return getUrlParams(params);
            } else {
                //可能就不是使用的application/json请求的接口，换成使用：application/x-www-form-urlencoded方式
                return getRequestParameterMap(request);
            }
        } catch (IOException e) {
           log.error(e.getMessage());
        }
        return new HashMap<>();
    }

    /**
     * 将map 转为 string
     * 将Map中的数据转换成key1=value1&key2=value2的形式 不包含签名域signature
     *
     * @see
     *
     * @param map
     * @return
     */
    public static String getUrlParams(Map<String, Object> map,
                                      boolean isSort) {
        if (map == null) {
            return "";
        }
        StringBuffer sb = new StringBuffer();
        List<String> keys = new ArrayList<>(map.keySet());
        if (isSort) {
            Collections.sort(keys);
        }
        for (int i = 0; i < keys.size(); i++) {
            String key = keys.get(i);
            Object value = map.get(key);
            if (XaUtils.isArray(value)) {
                String[] arr = (String[]) value;
                sb.append(key + "=" +  (arr.length == 1 ? arr[0] :  (arr.length > 1 ? Arrays.toString(arr) : "")));
            } else {
                sb.append(key + "=" + XaUtils.getNutNullStr(value, ""));
            }
            sb.append("&");
        }
        String s = sb.toString();
        if (s.endsWith("&")) {
            s = s.substring(0, s.lastIndexOf("&"));
        }
        return s;
    }

    /**
     * 获取请求参数中所有的信息
     *
     * @see
     *
     * @param request
     * @return
     */
    public static Map<String, String> getRequestParameterMap(final HttpServletRequest request) {
        Map<String, String> res = new HashMap<String, String>();
        Enumeration<?> temp = request.getParameterNames();
        if (null != temp) {
            while (temp.hasMoreElements()) {
                String en = (String) temp.nextElement();
                String value = request.getParameter(en);
                res.put(en, value);
                //在报文上送时，如果字段的值为空，则不上送<下面的处理为在获取所有参数数据时，判断若值为空，则删除这个字段>
                if (null == res.get(en) || "".equals(res.get(en))) {
                    res.remove(en);
                }
            }
        }
        return res;
    }
}
