package com.liquidnet.support.zuul.filter;

import com.liquidnet.commons.lang.util.JsonUtils;
import com.liquidnet.commons.lang.core.JwtValidator;
import com.liquidnet.service.ResponseDto;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.nio.charset.StandardCharsets;
import java.util.List;

@Slf4j
@Component
public class GlobalAuthFilter extends ZuulFilter {
    @Value("#{'${global.exclude.url}'.split(', ')}")
    private List<String> excludeUrls;

    @Autowired
    JwtValidator jwtValidator;

    @Override
    public String filterType() {
        return "pre";
    }

    @Override
    public int filterOrder() {
        return 2;
    }

    @Override
    public boolean shouldFilter() {
        RequestContext ctx = RequestContext.getCurrentContext();
        String requestURI = ctx.getRequest().getRequestURI();
//        return !excludeUrls.contains(requestURI);
        return false;
    }

    @Override
    public Object run() {
        RequestContext requestContext = RequestContext.getCurrentContext();
        HttpServletRequest httpServletRequest = requestContext.getRequest();
        String token = httpServletRequest.getHeader("authorization");
        Claims claims;
        try {
            log.info("token:{}", token);
            if (StringUtils.isBlank(token)) {
                requestContext.setSendZuulResponse(false);
                ResponseDto<Object> responseDto = ResponseDto.failure("401", "非法TOKEN");
                requestContext.setResponseBody(JsonUtils.toJson(responseDto));
                HttpServletResponse response = requestContext.getResponse();
                response.setCharacterEncoding(StandardCharsets.UTF_8.name());
                response.setContentType("application/json;charset=utf-8");
            } else {
                token = token.replace("Bearer ", "");
                // 解析没有异常则表示token验证通过，如有必要可根据自身需求增加验证逻辑
                claims = jwtValidator.parse(token);
                log.info("claims:{}", JsonUtils.toJson(claims));
//            claims = jwtUtil.parseJwtToken(token);
                // 对请求进行路由
                requestContext.setSendZuulResponse(true);
                // 请求头加入uid，传给具体的微服务
                requestContext.addZuulRequestHeader("uid", claims.get("uid").toString());
            }
        } catch (ExpiredJwtException expiredJwtEx) {
            log.error("TOKEN已过期:{}", token);
            // 不对请求进行路由
            requestContext.setSendZuulResponse(false);
            ResponseDto<Object> responseDto = ResponseDto.failure("402", "TOKEN已过期");
            requestContext.setResponseBody(JsonUtils.toJson(responseDto));
            HttpServletResponse response = requestContext.getResponse();
            response.setCharacterEncoding(StandardCharsets.UTF_8.name());
            response.setContentType("application/json;charset=utf-8");
        } catch (Exception ex) {
            log.error("TOKEN验证失败:{}", token);
            // 不对请求进行路由
            requestContext.setSendZuulResponse(false);
            ResponseDto<Object> responseDto = ResponseDto.failure("401", "非法TOKEN");
            requestContext.setResponseBody(JsonUtils.toJson(responseDto));
            HttpServletResponse response = requestContext.getResponse();
            response.setCharacterEncoding(StandardCharsets.UTF_8.name());
            response.setContentType("application/json;charset=utf-8");
        }
        return null;
    }
}
