package com.liang.common.config;

import com.liang.common.JsonTool;
import com.liang.common.utils.SecurityUtil;
import com.liang.common.utils.SystemConst;
import com.liang.entity.SysUserInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

import static com.liang.common.utils.SecurityUtil.getSysUserInfo;

/**
 * Restful方式登录<br>
 * 在参数中或者header里加参数login-token作为登录凭证<br>
 * 参数值是登录成功后的返回值中获取
 */

@Slf4j
@Component
public class AuthFilter extends OncePerRequestFilter {

    //     排除拦截地址
    private static List<String> excludedPaths = new ArrayList<>();

    static {
        excludedPaths.add("/home/**");
        excludedPaths.add("/login/**");
        excludedPaths.add("/images/**");
        excludedPaths.add("/api/**");
        excludedPaths.add("/css/**");
        excludedPaths.add("/excel/**");
        excludedPaths.add("/js/**");
        excludedPaths.add("/lib/**");
        excludedPaths.add("/files/**");
        excludedPaths.add("/updatePrj_AnnualBudgetDetail");
    }

    @Value("${KYGK.session-timeout}")
    private int sessionTimeout;
    private static String info = JsonTool.toJsonString(new ResponseInfo(HttpStatus.UNAUTHORIZED.value(), "token不存在或者过期"));

    @Override
    protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException {
        String uri = request.getServletPath();
        PathMatcher matcher = new AntPathMatcher();
        Optional<String> excludedOptional = excludedPaths.stream().filter(excludePath -> matcher.match(excludePath, uri)).findAny();
        return excludedOptional.isPresent();
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        if (isAccessAllowed(request, response)) {
            filterChain.doFilter(request, response);
        } else {
            writeResponse(response, request);
        }
    }

    private boolean isAccessAllowed(ServletRequest request, ServletResponse response) {
        if (HttpMethod.OPTIONS.name().equalsIgnoreCase(((HttpServletRequest) request).getMethod())) {
            return Boolean.TRUE;
        }


        try {

            SysUserInfo user = getSysUserInfo();
            if (null != user) {
                long timeout = SecurityUtil.getRedisUtil().getExpire(SystemConst.SYSTEM_USER_KEY + ":" + SecurityUtil.getUserKey());
                if (timeout > 0) {
                    SecurityUtil.getRedisUtil().set(SystemConst.SYSTEM_USER_KEY + ":" + SecurityUtil.getUserKey(), user, sessionTimeout);
                }
                return true;
            }
        } catch (Exception e) {
            return false;
        }
        return false;
    }

    private static void writeResponse(HttpServletResponse response, HttpServletRequest request) {
        writeResponse(response, request, info);
    }

    public static void writeResponse(HttpServletResponse response, HttpServletRequest request, String info) {
        try {
//            response.setStatus(status);
//            response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
//            response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
//            response.setHeader("Access-Control-Allow-Credentials", "true");
////            response.setContentType("application/json;charset=UTF-8");
//            response.sendRedirect("/home/index");
//            response.getWriter().write(info);

            if ("XMLHttpRequest".equals(request.getHeader("X-Requested-With"))) {
                //如果是ajax请求
                response.setContentType("application/json;charset=UTF-8");
                response.getWriter().write(info);
                response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            } else {
                response.sendRedirect("/home/index?loginStatus=redirect");
            }

        } catch (IOException e) {
        }
    }
}
