package com.qs.mp.handler.auth;

import com.alibaba.fastjson.JSONObject;
import com.qs.mp.common.enums.ServerEnvEnum;
import com.qs.mp.common.utils.LogUtil;
import com.qs.mp.common.utils.http.HttpHelper;
import com.qs.mp.core.domain.LoginUser;
import com.qs.mp.framework.security.handle.HostHolder;
import com.qs.mp.handler.BodyReaderHttpServletRequestWrapper;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

/**
 * @author daixiaodan
 *
 */

@Component
public class SignInterceptor implements HandlerInterceptor {

    public final static String ACCESS_TOKEN = "token";
    public final static String PARAM_SIGN = "sign";
    public final static int EXPIRE_TIME = 1440 * 1000; // 24h
    public final static int TOKEN_EXPIRE_CODE = 406 ;
    protected Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private HostHolder hostHolder;

    @Value(value = "${server.env}")
    private String env;




    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //logger.info("request URL:" + getRequestInfo(request));
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }
        if (ServerEnvEnum.DEV.getCode().equals(env)) {
            return true;
        }

        // 测试环境swagger放行校验
        if (ServerEnvEnum.TEST.getCode().equals(env)) {
            String swagger = request.getHeader("swagger");
            if (StringUtils.isNotBlank(swagger)) {
                return true;
            }
        }

        String method = request.getMethod();
        if ("post".equalsIgnoreCase(method)) {
            // 最后用RequestBody中获取token
            ServletRequest tempRequest = null;
            tempRequest = new BodyReaderHttpServletRequestWrapper(request);
            String body = HttpHelper.getBodyString(tempRequest);
            String timestamp = request.getHeader("x-zz-timestamp");
            //进行sign验证
            String[] signs = request.getParameterValues("sign");

            if (request.getRequestURI().equals("/api/v1/mp/wx/urlschema/generate")
                || request.getRequestURI().equals("/api/v1/mp/wx/code/generate")
                || request.getRequestURI().equals("/api/v1/mp/open/link/wx/scheme")) {
                // 小程序跳转页面请求
                LogUtil.debug(logger, "requestURI:" + request.getRequestURI());
                return true;
            }
            if(null == signs || signs.length == 0) {
                logger.error("sign参数为空 request url:"+getRequestInfo(request));
                response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
                return false;
            }
            if(StringUtils.isBlank(body)){
                logger.info("request body is null. request url:"+getRequestInfo(request));
                //response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
                return true;
            }

            String sign = signs.length> 0 ? signs[0] : "";
            boolean verify =SignUtils.verifySign(sign, body, timestamp);
            long time = Long.valueOf(timestamp);
            if(StringUtils.isBlank(timestamp)) {
                logger.error("请求时间无效或者超时");
                response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
                return false;
            } else if(!verify) {
                logger.error("sign参数无效");
                response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
                return false;
            } /*else if (System.currentTimeMillis() - time > EXPIRE_TIME) {
                logger.error("request time expire... request URL:" + getRequestInfo
                        (request)+" x-zz-timestamp:"+time);
                response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
                return false;
            }*/

        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {

    }

    private String getRequestInfo(HttpServletRequest request) {
        return request.getRequestURL().toString() + " query param:" + request.getQueryString();
    }

    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {

    }

}
