package com.jiayue.ssi.filter;

import cn.hutool.json.JSONUtil;
import com.jiayue.ssi.constant.SecretKeyConstants;
import com.jiayue.ssi.servlet.ParameterRequestWrapper;
import com.jiayue.ssi.util.ResponseInfo;
import com.jiayue.ssi.util.SM2CryptUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.annotation.Order;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
* 验证sm过滤器
*
* @author xsl
* @since 2023/02/27
*/
@Order(4)
public class VerifySmFilter extends OncePerRequestFilter {
    private String defaultFilterProcessUrl = "/user/login";

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        // 不是登录操作
//        if (!("POST".equalsIgnoreCase(request.getMethod()) && defaultFilterProcessUrl.equals(request.getServletPath()))) {
//            // 验证token
//            String tokenStr = request.getHeader("Authorization");
//            if (StringUtils.isNotEmpty(tokenStr)){
//                // 解密token
//                String decryptTokenStr = SM2CryptUtils.decrypt(tokenStr,SecretKeyConstants.SERVER_PRIVATE_KEY);
//                System.out.println("接收token后解密："+decryptTokenStr);
//                String tokenSign = request.getHeader("TokenSign");
//                // 验证签名
//                boolean verifySign = SM2CryptUtils.verifySign(SecretKeyConstants.CLIENT_PUBLIC_KEY,decryptTokenStr,tokenSign);
//                if (!verifySign){
//                    // 验签失败
//                    ResponseInfo.doResponse(response,"token验签失败,不能访问系统！",401);
//                    return;
//                }
//            }
//            else{
//                ResponseInfo.doResponse(response,"没有令牌权限,不能访问系统！",401);
//                return;
//            }
//        }
        // 解密后的参数字符串
        String decryptStr = "";
        if ("POST".equalsIgnoreCase(request.getMethod())){
            // 验证加密的参数文本
            String data_sm2 = request.getParameter("secretData");
            if (StringUtils.isNotEmpty(data_sm2)){
                System.out.println("接收前端加密："+data_sm2);
                try {
                    decryptStr = SM2CryptUtils.decrypt(data_sm2, SecretKeyConstants.SERVER_PRIVATE_KEY);
                }
                catch (Exception e){
                    // 参数验签失败
                    ResponseInfo.doResponse(response,"参数解密失败,不能访问系统！",401);
                    return;
                }
                System.out.println("解密后：" + decryptStr);
                // 验签前端参数
                String paramSign = request.getParameter("paramSign");
                try {
                    // 验证签名
                    boolean verifySign = SM2CryptUtils.verifySign(SecretKeyConstants.CLIENT_PUBLIC_KEY, decryptStr, paramSign);
                    if (!verifySign){
                        // 验签失败
                        ResponseInfo.doResponse(response,"参数验签失败,不能访问系统！",401);
                        return;
                    }
                }
                catch (Exception e){
                    // 验签失败
                    ResponseInfo.doResponse(response,"参数验签失败,不能访问系统！",401);
                    return;
                }
            }
        }
        else{
            // get请求无参数，取出是null
            String get_sm2Str = request.getParameter("0");
            if (StringUtils.isNotEmpty(get_sm2Str)){
                String[] tempStr = get_sm2Str.split("&");
                Map<String,String> tempMap = new HashMap(16);
                for (int i=0;i<tempStr.length;i++){
                    String[] fieldStr = tempStr[i].split("=");
                    tempMap.put(fieldStr[0],fieldStr[1]);
                }
                // 对加密串解密验签
                System.out.println("接收get请求secretData："+tempMap.get("secretData"));
                try {
                    decryptStr = SM2CryptUtils.decrypt(tempMap.get("secretData"), SecretKeyConstants.SERVER_PRIVATE_KEY);
                }
                catch (Exception e){
                    // 参数验签失败
                    ResponseInfo.doResponse(response,"参数解密失败,不能访问系统！",401);
                    return;
                }
                System.out.println("解密后：" + decryptStr);
                // 验签前端参数
                String paramSign = tempMap.get("paramSign");
                // 验证签名
                try {
                    boolean verifySign = SM2CryptUtils.verifySign(SecretKeyConstants.CLIENT_PUBLIC_KEY, decryptStr, paramSign);
                    if (!verifySign){
                        // 验签失败
                        ResponseInfo.doResponse(response,"参数验签失败,不能访问系统！",401);
                        return;
                    }
                }
                catch (Exception e){
                    // 验签失败
                    ResponseInfo.doResponse(response,"参数验签失败,不能访问系统！",401);
                    return;
                }
            }
        }

        Map<String,Object> stringToMap = new HashMap(16);
        if (!"".equals(decryptStr)){
            if ("POST".equalsIgnoreCase(request.getMethod())){
                String[] tempInterval = decryptStr.split("&");
                for (int i=0;i<tempInterval.length;i++){
                    String[] fieldKeyValue = tempInterval[i].split("=");
                    stringToMap.put(fieldKeyValue[0],fieldKeyValue[1]);
                }
            }
            else{
                stringToMap = JSONUtil.parseObj(decryptStr).getRaw();
            }
        }
        ParameterRequestWrapper pr = new ParameterRequestWrapper(request, stringToMap);
        filterChain.doFilter(pr, response);
    }
}
