package com.testor.common.interceptor;

import com.testor.biz.auth.model.AuthModel;
import com.tongtech.tfw.backend.common.constants.enumeration.BaseStatusEnum;
import com.tongtech.tfw.backend.common.constants.enumeration.HttpStatusCodeEnum;
import com.tongtech.tfw.backend.common.jwt.JwtHelper;
import com.tongtech.tfw.backend.common.models.jwt.JwtInfos;
import com.tongtech.tfw.backend.common.request.RequestUtil;
import com.tongtech.tfw.backend.common.response.ResponseUtil;
import com.tongtech.tfw.backend.core.helper.StringHelper;
import io.jsonwebtoken.ExpiredJwtException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.PathMatcher;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.function.Predicate;

public class AuthInterceptor implements HandlerInterceptor {

    private static Logger log = LoggerFactory.getLogger(AuthInterceptor.class);

    @Autowired
    private PathMatcher pathMatcher;

    public AuthInterceptor() {
    }

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object obj) {
        HttpServletResponse httpResponse = response;
        String token = RequestUtil.getToken(request);
        //log.info("接口路径：" + request.getRequestURI() + ";token=" + token);
        if (StringHelper.isNotBlank(token)) {
            try {
                JwtInfos jwtInfos = JwtHelper.parseJwtAuth0(token, "Token Issuer");
                String userId = jwtInfos.getUserId();
                if (!StringUtils.hasText(userId)) {
                    httpResponse.setStatus(401);
                    this.sendUnauthorizedFail(request, response);
                } else {
                    return true;
                }
            } catch (ExpiredJwtException var16) {
                this.sendExpiredJwt(request, response);
                return false;
            }
        }
        response.setStatus(403);
        this.sendForbiddenFail(request, response);
        return false;

    }

    private Predicate<AuthModel> match(String method, String requestUri) {
        return (res) -> {
            return this.pathMatcher.match(res.getResourceUrl(), requestUri);
        };
    }

    private boolean anyMatch(List<AuthModel> perms, String method, String requestUri) {
        return perms.stream().anyMatch(this.match(method, requestUri));
    }

    private void sendForbiddenFail(ServletRequest request, ServletResponse response) {
        ResponseUtil.response((HttpServletRequest) ((HttpServletRequest) request), (HttpServletResponse) ((HttpServletResponse) response), HttpStatusCodeEnum.FORBIDDEN, (Exception) null);
    }

    private void sendNotFoundFail(ServletRequest request, ServletResponse response) {
        ResponseUtil.response((HttpServletRequest) ((HttpServletRequest) request), (HttpServletResponse) ((HttpServletResponse) response), HttpStatusCodeEnum.NOT_FOUND, (Exception) null);
    }

    private void sendUnauthorizedFail(ServletRequest request, ServletResponse response) {
        ResponseUtil.response((HttpServletRequest) ((HttpServletRequest) request), (HttpServletResponse) ((HttpServletResponse) response), BaseStatusEnum.UNAUTHORIZED.transform(), (Exception) null);
    }

    private void sendExpiredJwt(ServletRequest request, ServletResponse response) {
        ResponseUtil.response((HttpServletRequest) ((HttpServletRequest) request), (HttpServletResponse) ((HttpServletResponse) response), BaseStatusEnum.TOKEN_INVALID.transform(), (Exception) null);
    }
}

