package com.community.huiju.filter;

import com.alibaba.fastjson.JSONObject;
import com.community.huiju.common.base.ResponseBean;
import com.community.huiju.common.perproties.DaSuProperties;
import com.community.huiju.common.sign.DaSuSign;
import com.community.huiju.enums.ResponseErrorsMessages;
import com.community.huiju.exception.WisdomException;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.PrintWriter;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.util.Map;
import java.util.TreeMap;

/**
 *
 * 签名拦截器
 *
 * @author weiximei on 2019-05-17
 */
//@Component
@Slf4j
public class SignFilter implements Filter {

    private String [] urls = new String[]{
            "/**/swagger-ui.html/**","/**/springfox-swagger-ui/**",
            "/**/swagger-resources/**","/**/v2/api-docs/**",
            "/**/swagger-resources/**"
    };

    private AntPathMatcher antPathMatcher = new AntPathMatcher();

    @Autowired
    private DaSuProperties daSuProperties;

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        for (String url : urls) {
            if (antPathMatcher.match(url ,httpServletRequest.getRequestURI())) {
                chain.doFilter(request, response);
                return;
            }
        }

        ResponseBean responseBean = new ResponseBean();
        TreeMap<String, Object> treeMap = Maps.newTreeMap();

        try {
            // 加密方式
            String encrypt = request.getParameter("encrypt");
            if (!"md5".equals(encrypt.toLowerCase())) {
                responseBean.addError(ResponseErrorsMessages.SIGN_ENCRYPT_MD5_ERROR.getCode(), ResponseErrorsMessages.SIGN_ENCRYPT_MD5_ERROR.getMsg());
                responseWriter(response, responseBean);
                return;
            }

            String datetime = request.getParameter("datetime");
            LocalDateTime localDateTime =LocalDateTime.ofEpochSecond(Long.valueOf(datetime),0, ZoneOffset.ofHours(8));
            localDateTime.plusMinutes(10);

            // 校验签名是否过期
            if (StringUtils.isBlank(datetime) || System.currentTimeMillis() > Long.valueOf(datetime)) {
                responseBean.addError(ResponseErrorsMessages.SIGN_DATETIME_ERROR.getCode(), ResponseErrorsMessages.SIGN_DATETIME_ERROR.getMsg());
                responseWriter(response, responseBean);
                return;
            }
        } catch (Exception e) {
            responseBean.addError(ResponseErrorsMessages.SIGN_ERROR.getCode(), ResponseErrorsMessages.SIGN_ERROR.getMsg());
            responseWriter(response, responseBean);
            return;
        }




        // 获取请求的所有参数
        Map<String, String[]> parameterMap = request.getParameterMap();
        parameterMap.entrySet().forEach(e-> {
            String key = e.getKey();
            String [] value = e.getValue();
            if (!"sign".equals(key) && !"appSecret".equals(key)) {
                treeMap.put(key, value[0]);
            }
        });

        String sign = DaSuSign.createSign(treeMap, daSuProperties.getAppSecret());
        String parameterSign = request.getParameter("sign");

        if (DaSuSign.isMD5Sign(sign, parameterSign)) {
            chain.doFilter(request, response);
        } else {
            responseBean.addError(ResponseErrorsMessages.SIGN_ERROR.getCode(), ResponseErrorsMessages.SIGN_ERROR.getMsg());
            responseWriter(response, responseBean);
        }

    }

    private void responseWriter(ServletResponse response, ResponseBean responseBean) {
        response.setContentType("application/json;charset=UTF-8");
        PrintWriter writer = null;
        try {
            writer = response.getWriter();
        } catch (IOException e) {
            e.printStackTrace();
        }
        writer.write(JSONObject.toJSONString(responseBean));
        writer.flush();
        writer.close();
    }
}
