package org.springblade.common.auth.security;

import com.alibaba.fastjson.JSON;
import org.springblade.common.auth.UserContext;
import org.springblade.common.auth.UserContextUtil;
import org.springblade.common.auth.permission.DisableLoginVerify;
import org.springblade.common.auth.support.AuthErrorConstants;
import org.springblade.common.auth.support.AuthUtil;
import com.wn.common.controller.BaseController;
import com.wn.common.datamodel.ResultDTO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import lombok.Setter;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

/**
 *AccessToken校验拦截器，防止csrf攻击。
 */
@Component
public class AccessTokenInterceptor implements HandlerInterceptor {

    private static final Logger logger = LoggerFactory.getLogger(AccessTokenInterceptor.class);
    
    @Value("${security.accesstoken.check.flag:false}")
    @Setter
    private boolean accessTokenCheckFlag = false; //是否检查accessToken开关
    
    @Value("${security.permission.check.flag:true}")
    @Setter
    private boolean permissionCheckFlag = true; //是否检查权限校验开关
    
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        if (!accessTokenCheckFlag) {
            return true;
        }
        if (!permissionCheckFlag) {
            return true;
        }
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }
        HandlerMethod handlerMethod = (HandlerMethod) handler;

        if (!(handlerMethod.getBean() instanceof BaseController)) {
            return true;
        }

        if (handlerMethod.hasMethodAnnotation(DisableLoginVerify.class)) {
            return true;
        }
        
        UserContext userContext = UserContextUtil.getUserContext(request.getSession());
        if (userContext.isInnerLoginUser()) { //内部登录用户不做检验
            return true;
        }

        String accessToken = userContext.getAccessToken();
        String inputAccessToken = request.getHeader(AuthUtil.ACCESS_TOKEN_KEY);
        if (StringUtils.isBlank(inputAccessToken) || !inputAccessToken.equalsIgnoreCase(accessToken)) {
            response.setContentType(AuthUtil.CONTENT_TYPE_JSON);
            response.getWriter().write(createErrorResp(AuthErrorConstants.INVALID_ACCESS_TOKEN));
            response.setHeader(AuthUtil.ACCESS_TOKEN_KEY, accessToken);
            response.getWriter().flush();
            return false;
        }
        return true;
    }

    public String createErrorResp(AuthErrorConstants error) {
        ResultDTO<?> errorResult = new ResultDTO<>();
        errorResult.setCode(error.getCode());
        errorResult.setMessage(error.getMessage());
        errorResult.setSuccess(false);
        String errorResp = JSON.toJSONString(errorResult);
        return errorResp;
    }
    
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView mv)
            throws Exception {
        //logger.info("AccessTokenInterceptor.postHandle()...");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
        //logger.info("AccessTokenInterceptor.afterCompletion()...");
    }
    
}
