package com.izouma.jmrh.config;

import cn.licoy.encryptbody.config.EncryptBodyConfig;
import cn.licoy.encryptbody.util.AESEncryptUtil;
import cn.licoy.encryptbody.util.CheckUtils;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.IOException;
import java.util.Map;

@Component
@Order(1)
@AllArgsConstructor
@Slf4j
public class DecryptFilter implements Filter {

    private final EncryptBodyConfig config;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        String contentType = ((HttpServletRequest) servletRequest).getHeader("content-type");
        String encrypted = ((HttpServletRequest) servletRequest).getHeader("content-encrypted");
        if ("true".equals(encrypted) && !"application/json".equals(contentType)) {
            filterChain.doFilter(new EncryptedRequest(servletRequest, config), servletResponse);
        } else {
            filterChain.doFilter(servletRequest, servletResponse);
        }
    }

    @Override
    public void destroy() {
        Filter.super.destroy();
    }

    @Slf4j
    static class EncryptedRequest extends HttpServletRequestWrapper {

        private final EncryptBodyConfig config;

        public EncryptedRequest(ServletRequest request, EncryptBodyConfig config) {
            super((HttpServletRequest) request);
            this.config = config;
        }


        public String getParameter(String paramName) {
            String value = super.getParameter(paramName);
            if (StringUtils.isNotBlank(value)) {
                try {
                    AESEncryptUtil.decrypt(value, config.getAesKey());
                } catch (Exception e) {
                    log.error("解密失败", e);
                }
            }
            return value;
        }

        public String[] getParameterValues(String paramName) {
            String[] values = super.getParameterValues(paramName);
            if (values != null) {
                for (int index = 0; index < values.length; index++) {
                    if (StringUtils.isNotBlank(values[index])) {
                        try {
                            values[index] = AESEncryptUtil.decrypt(values[index], config.getAesKey());
                        } catch (Exception e) {
                            log.error("解密失败", e);
                        }
                    }
                }
            }
            return values;
        }
    }
}
