package com.happy.Until;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import com.alibaba.fastjson.JSON;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class GetHttpParam {

    public static JSONObject getHttpParam(HttpServletRequest request){
        //处理业务业务
        JSONObject jsonObject = new JSONObject();
        try {
            BufferedReader streamReader = new BufferedReader( new InputStreamReader(request.getInputStream(), "UTF-8"));
            StringBuilder responseStrBuilder = new StringBuilder();
            String inputStr;
            while ((inputStr = streamReader.readLine()) != null)
                responseStrBuilder.append(inputStr);

            jsonObject = JSONObject.parseObject(responseStrBuilder.toString(), Feature.OrderedField);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return jsonObject;
    }

    /**
     *  获取request中参数
     * @param request 页面请求
     */
    public static JSONObject getRequestParameters(HttpServletRequest request) {
        String parameters="";//请求参数
        if("GET".equals(request.getMethod())){//GET请求时的参数
            String urlParameter=request.getQueryString();//网址中的参数
            if(urlParameter!=null&&!"".equals(urlParameter)){
                try {
                    urlParameter= URLDecoder.decode(urlParameter,"UTF-8");
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
            }else {
                urlParameter="";
            }
            parameters=urlParameter;
        }else if("POST".equals(request.getMethod())){//POST请求时的参数
            String totalParameter="";//表单及网址中全部参数
            Map<String, String[]> params = request.getParameterMap();
            int parametersNum=request.getParameterMap().size();//参数个数
            int flag=1;
            for (String key : params.keySet()) {

                String[] values = params.get(key);
                for (int i = 0; i < values.length; i++) {
                    String value = values[i];
                    totalParameter+= key + "=" + value;
                }
                if(flag<parametersNum){
                    totalParameter+="&";
                }
                flag+=1;
            }
            parameters=totalParameter;
        }
        Map<String, Object> map=new HashMap<String, Object>();
        String[] arr=parameters.split("&");
        for (int i = 0; i <arr.length; i++) {
            String key=arr[i].substring(0, arr[i].indexOf("="));
            String value=arr[i].substring( arr[i].indexOf("=")+1);
            map.put(key, value);
        }
        return JSON.parseObject(mapToJson(map));
    }

    /**
     *  获取request中参数
     * @param request 页面请求
     */
    public static String getRequestStringParameters(HttpServletRequest request) {
        String parameters="";//请求参数
        if("GET".equals(request.getMethod())){//GET请求时的参数
            String urlParameter=request.getQueryString();//网址中的参数
            if(urlParameter!=null&&!"".equals(urlParameter)){
                try {
                    urlParameter= URLDecoder.decode(urlParameter,"UTF-8");
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
            }else {
                urlParameter="";
            }
            parameters=urlParameter;
        }else if("POST".equals(request.getMethod())){//POST请求时的参数
            String totalParameter="";//表单及网址中全部参数
            Map<String, String[]> params = request.getParameterMap();
            int parametersNum=request.getParameterMap().size();//参数个数
            int flag=1;
            for (String key : params.keySet()) {

                String[] values = params.get(key);
                for (int i = 0; i < values.length; i++) {
                    String value = values[i];
                    totalParameter+= key + "=" + value;
                }
                if(flag<parametersNum){
                    totalParameter+="&";
                }
                flag+=1;
            }
            parameters=totalParameter;
        }
        Map<String, Object> map=new HashMap<String, Object>();
        String[] arr=parameters.split("&");
        for (int i = 0; i <arr.length; i++) {
            String key=arr[i].substring(0, arr[i].indexOf("="));
            String value=arr[i].substring( arr[i].indexOf("=")+1);
            map.put(key, value);
        }
        return mapToJson(map);
    }

    public static String mapToJson(Map<String, Object> map) {
        String data = JSON.toJSONString(map);
        return data;
    }

    public static <T> T parameterMapToBean(HttpServletRequest req, Class<T> clazz) throws ClassNotFoundException {
        //获得参数的map集合
        Map<String, String[]> map = req.getParameterMap();

        //获取实体类的对象
        T bean = null;
        try {
            bean = clazz.newInstance();
        } catch (InstantiationException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }

        //获取实体类的所有方法
        Method[] methods = clazz.getDeclaredMethods();
        //开始遍历实体类方法
        for (Method method : methods) {
            //判断方法名是否以set开头
            if (method.getName().startsWith("set")) {
                //遍历map集合中的key
                for (Map.Entry<String, String[]> entry : map.entrySet()) {
                    //判断方法名末尾是否和map的key一致,比较的时候将方法名全部转为小写
                    if (method.getName().toLowerCase().endsWith(entry.getKey().toLowerCase())) {
                        //遍历map中的value值,因为map中是以 k1={v1,v2} ,k2={v3,v4}的形式存储数据的
                        try {
                            for (String e : entry.getValue()) {
                                //获取set方法中的参数类型
                                Class<?>[] parameterTypes = method.getParameterTypes();
                                //因为set方法的参数类型只有一个,所以取第一个
                                Class<?> parameterType = parameterTypes[0];
                                //获得参数类型的名字
                                String simpleName = parameterType.getSimpleName();
                                //比较参数类型名并将获得的String类型的数据转换为对应实体类的数据
                                if ("String".equals(simpleName)) {
                                    method.invoke(bean, e);
                                } else if ("Integer".equals((simpleName)) || "int".equals((simpleName))) {
                                    int ee = Integer.parseInt(e);
                                    method.invoke(bean, ee);
                                } else if ("Double".equals((simpleName)) || "double".equals((simpleName))) {
                                    double ee = Double.parseDouble(e);
                                    method.invoke(bean, ee);
                                }
                                //其他类型可以添加,以上举出常用的数据类型
                            }
                        } catch (IllegalAccessException e) {
                            throw new RuntimeException(e);
                        } catch (InvocationTargetException e) {
                            throw new RuntimeException(e);
                        }
                    }
                }

            }

        }
        //返回对象
        return bean;
    }

    private static Class getClass(String simpleName) throws ClassNotFoundException {
        Matcher matcher = Pattern.compile("(?<=\\<L)(\\S+)(?=\\;>)").matcher(simpleName);
        if (matcher.find()) {
            String classUrl = matcher.group().replace("/",".");
            Class c=Class.forName(classUrl);
            return c;
        }
        return null;
    }

    public static String getRequestPostData(HttpServletRequest request) throws IOException {
        int contentLength = request.getContentLength();
        if (contentLength < 0) {
            return null;
        }
        byte[] buffer = new byte[contentLength];
        for (int i = 0; i < contentLength; ) {
            int len = request.getInputStream().read(buffer, i, contentLength - i);
            if (len == -1) {
                break;
            }
            i += len;
        }
        return new String(buffer, StandardCharsets.UTF_8);
    }
}
