package com.liangjian.dataplatform.member.interceptor;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectReader;
import com.liangjian.dataplatform.member.entity.token.JwtToken;
import com.liangjian.dataplatform.member.safe.Tuple3;
import com.liangjian.dataplatform.member.util.JwtUtil;
import com.liangjian.dataplatform.member.util.LoginUserInfo;
import com.liangjian.dataplatform.member.util.http.SimpleHttpClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * @Author: 黄子奇
 * @Date: 2019/10/8 15:51
 */
@Component
public class PermInterceptor implements HandlerInterceptor {
    @Value("${getTokenUrl}")
    private String url;
    @Value("${jwt-secret}")
    private String jwtSecret;
    private static List<String> anonUrls = Arrays.asList("/doc.html", "/swagger*","/try/*", "/webjars/*", "/error","/v2/*", "/superset/*","/weixin*");

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String uri = request.getRequestURI();
        if(judgeAnon(uri)) {
            return true;
        }

        String ssoToken = request.getHeader("Sso-Token");
        if(ssoToken == null || ssoToken.isEmpty()) {
            return failResponse(response, "没有token，请重新登陆");
        } else {
            Tuple3<Boolean,String,Exception> httpResult = SimpleHttpClient.httpGet(url + "?staffId=" + ssoToken);
            if(!httpResult.get_1()) {
                httpResult.get_3().printStackTrace();
                return failResponse(response, "获取token失败，请稍后尝试");
            }
            String jwtJs = httpResult.get_2();
            ObjectReader objectReader = new ObjectMapper().readerFor(new TypeReference<Map<String,String>>() {});
            Map<String,String> jwtObj = objectReader.readValue(jwtJs);

            //校验token
            String jwt = jwtObj.get("jwt");
            if(!JwtUtil.verify(jwt, jwtSecret)) {
                return failResponse(response, "token验证失败");
            }

            JwtToken jwtToken = JwtUtil.getPayload(jwtObj.get("jwt"));

            LoginUserInfo.userInfo.set(jwtToken);
            Map<String,Object> permission = jwtToken.getPermission();
            boolean hasPermission = permission.keySet().contains(uri);

            if(hasPermission) {
                return true;
            } else {
                return failResponse(response, "没有此权限");
            }
        }
    }

    private boolean judgeAnon(String uri) {
        for (String anonUrl : anonUrls) {
            if(anonUrl.endsWith("*")) {
                String anonUrlWithout = anonUrl.replace("*","");
                if(uri.startsWith(anonUrlWithout)) {
                    return true;
                }
            } else {
                if(uri.equalsIgnoreCase(anonUrl)){
                    return true;
                }
            }
        }
        return false;
    }

    private boolean failResponse(HttpServletResponse response,String msg) {
        response.setCharacterEncoding("utf-8");
        response.setContentType("application/json");
        try {
            response.getWriter().write("{\"success\":false,\"msg\":\""+ msg +"\"}");
            return false;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
    }
}
