package org.springblade.common.filter.utils;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.symmetric.SymmetricAlgorithm;
import cn.hutool.extra.servlet.ServletUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.hutool.jwt.signers.AlgorithmUtil;
import com.alibaba.fastjson.JSON;
import lombok.Cleanup;
import lombok.extern.slf4j.Slf4j;
import org.springblade.common.filter.http.ModifyRequestBodyWrapper;
import org.springblade.common.filter.http.ModifyResponseBodyWrapper;
import org.springblade.core.tool.utils.DigestUtil;
import org.springblade.wx.config.ConfigForClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Component;
import org.springframework.util.Base64Utils;

import javax.annotation.Resource;
import javax.crypto.SecretKey;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.sql.Struct;
import java.util.*;
import java.util.function.Function;

import static cn.hutool.core.util.StrUtil.*;

/**
 * @author cy-computer
 */
@Slf4j
@Component
public class HttpUtil {

	@Resource
	private CryptoConfig cryptoConfig;


	public void modifyHttpData(ServletRequest request, ServletResponse response, FilterChain chain) throws Exception {
		HttpServletRequest originalRequest = (HttpServletRequest) request;
		String url = originalRequest.getRequestURI();
		if (HttpMethod.POST.matches(originalRequest.getMethod()) && !this.isInWhiteList(url)) {
			//只处理不在白名单下的post请求
			this.handelPost(request,response,chain,originalRequest);
		}else{
			//其他请求直接通过
			chain.doFilter(request,response);
		}
	}

	/**
	 * 修改请求体和请求类型
	 *
	 * @param request           原请求
	 * @param modifyRequestBody 修改后的请求体
	 * @param contentType       请求类型
	 * @return
	 */
	public ModifyRequestBodyWrapper modifyRequestBodyAndContentType(ServletRequest request, String modifyRequestBody, String contentType) {
		log.debug("ContentType改为 -> {}", contentType);
		HttpServletRequest orginalRequest = (HttpServletRequest) request;
		return new ModifyRequestBodyWrapper(orginalRequest, modifyRequestBody, contentType);
	}

	/**
	 * 处理post请求
	 * @param request
	 * @param response
	 * @param chain
	 * @param originalRequest
	 * @throws Exception
	 */
	private void handelPost(ServletRequest request, ServletResponse response, FilterChain chain,HttpServletRequest originalRequest) throws Exception {
		//密文
		String originalRequestBody = ServletUtil.getBody(request);
		if (StrUtil.isNotBlank(originalRequestBody)) {
			//报文不为空，解密
			String modifyRequestBody = SecureUtil.aes(cryptoConfig.getKey().getBytes()).decryptStr(originalRequestBody);
			request = this.modifyRequestBodyAndContentType(originalRequest, modifyRequestBody, null);
		}
		chain.doFilter(request, response);
	}

	/**
	 * 白名单配置
	 * @param uri
	 * @return
	 */
	private boolean isInWhiteList(String  uri){
		for(String url: cryptoConfig.getWhiteList()){
			if(uri.contains(url)){
				return true;
			}
		}
		return false;
	}

}
