package com.eitc.common.filter;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.eitc.common.config.ParameterRequestWrapper;
import com.eitc.common.constant.HttpConst;
import com.eitc.common.utils.CryptoUtil;
import com.eitc.common.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.stream.Collectors;


/**
 * Repeatable 过滤器
 *
 * @author eitc
 */
@Slf4j
public class RepeatableFilter implements Filter {

    private static final String DECRYPT_PARAM_NAME = "decrypt";//请求参数包含的是否加密的字段

    private static final String DEFAULT_DECRYPT_TYPE = "AES";//默认加密的类型

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse res = (HttpServletResponse) response;
        {
            String contentType = req.getContentType();//获取contentType请求头
            if (StringUtils.isNotBlank(contentType)) {
                String method = req.getMethod();//获取请求方法  post/get
                //2 处理post请求  只处理application/x-www-form-urlencoded  application/json,对于multipart/form-data，直接放行
                if (method.trim().equalsIgnoreCase(HttpConst.POST_METHOD) || method.trim().equalsIgnoreCase(HttpConst.PUT_METHOD)) {
                    if (contentType.trim().toLowerCase().contains(HttpConst.MULTIPART_CONTENT_TYPE)) {
                        chain.doFilter(req, response);
                        return;
                    }
                    //处理application/x-www-form-urlencoded
                    if (contentType.trim().toLowerCase().contains(HttpConst.FORM_URLENCODED_CONTENT_TYPE)) {
                        String decrypt = request.getParameter(DECRYPT_PARAM_NAME);
                        if (decrypt == null || decrypt.trim().isEmpty()) {
                            chain.doFilter(request, response);
                            return;
                        }
                        chain.doFilter(req, response);
                        return;
                    }
                    //处理application/json
                    if (contentType.trim().toLowerCase().contains(HttpConst.JSON_CONTENT_TYPE)) {
                        ParameterRequestWrapper requestWrapper = new ParameterRequestWrapper(req);
                        try {
                            String collect = requestWrapper.getReader().lines().collect(Collectors.joining(System.lineSeparator()));
                            // 解密
                            String decrypt = CryptoUtil.decrypt(collect);
                            String jsonString = null;
                            try {
                                JSONObject parseObject = JSONObject.parseObject(decrypt);
                                jsonString = parseObject.toJSONString();
                            } catch (Exception e) {
                                JSONArray jsonArray = JSONArray.parseArray(decrypt);
                                jsonString = jsonArray.toJSONString();
                            }
                            byte[] bytes = jsonString.getBytes(StandardCharsets.UTF_8);
                            ByteArrayOutputStream binaryStream = new ByteArrayOutputStream();
                            try {
                                binaryStream.write(bytes);
                                byte[] byteArray = binaryStream.toByteArray();
                                requestWrapper.setInputStream(byteArray);
                            } catch (IOException e) {
                                e.printStackTrace();
                            } finally {
                                try {
                                    binaryStream.close();
                                } catch (IOException e) {
                                    e.printStackTrace();
                                }
                            }
                        } catch (Exception e) {
                            log.error("解密失败：" + req.getContextPath(), e);
                        }
                        chain.doFilter(requestWrapper, response);
                        return;
                    }
                }
            }
        }


        HttpServletRequest requestWrapper = null;
        if (req instanceof HttpServletRequest
                && StringUtils.startsWithIgnoreCase(req.getContentType(), MediaType.APPLICATION_JSON_VALUE)) {
            requestWrapper = new RepeatedlyRequestWrapper((HttpServletRequest) request, response);
        }
        if (null == requestWrapper) {
            chain.doFilter(req, res);
        } else {
            chain.doFilter(requestWrapper, res);
        }
    }

    @Override
    public void destroy() {

    }


}
