package com.eitc.common.config;

import org.springframework.util.StreamUtils;

import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;










public class ParameterRequestWrapper  extends HttpServletRequestWrapper {
    private Map<String , String[]> params = new HashMap<String, String[]>();
    /**
     * 缓存下来的HTTP body
     */
    private byte[] body;


    @SuppressWarnings("unchecked")
    public ParameterRequestWrapper(HttpServletRequest request) throws IOException {
        // 将request交给父类，以便于调用对应方法的时候，将其输出，其实父亲类的实现方式和第一种new的方式类似
        super(request);
        //将参数表，赋予给当前的Map以便于持有request中的参数
        this.params.putAll(request.getParameterMap());
        //将参数表，赋予给当前的Map以便于持有request中的参数
        this.body = StreamUtils.copyToByteArray(request.getInputStream());
    }
    //重载一个构造方法
    public ParameterRequestWrapper(HttpServletRequest request , Map<String , Object> extendParams) throws IOException {
        this(request);
        addAllParameters(extendParams);//这里将扩展参数写入参数表
    }


    public void addAllParameters(Map<String , Object>otherParams) {//增加多个参数
        for(Map.Entry<String , Object>entry : otherParams.entrySet()) {
            addParameter(entry.getKey() , entry.getValue());
        }
    }


    public void addParameter(String name , Object value) {//增加参数
        if(value != null) {
            if(value instanceof String[]) {
                this.params.put(name , (String[])value);
            }else if(value instanceof String) {
                this.params.put(name , new String[] {(String)value});
            }else {
                this.params.put(name , new String[] {String.valueOf(value)});
            }
        }
    }




    /**
     * 重新包装输入流
     * @return
     * @throws IOException
     */
    @Override
    public ServletInputStream getInputStream() throws IOException {
        InputStream bodyStream = new ByteArrayInputStream(body);
        return new ServletInputStream() {

            @Override
            public int read() throws IOException {
                return bodyStream.read();
            }

            /**
             * 下面的方法一般情况下不会被使用，如果你引入了一些需要使用ServletInputStream的外部组件，可以重点关注一下。
             * @return
             */
            @Override
            public boolean isFinished() {
                return false;
            }

            @Override
            public boolean isReady() {
                return true;
            }

            @Override
            public void setReadListener(ReadListener readListener) {

            }
        };
    }

    @Override
    public BufferedReader getReader() throws IOException {
        return new BufferedReader(new InputStreamReader(getInputStream()));
    }

    public void setInputStream( byte[] in) {
        this.body = in;
    }


}
