package cn.quantgroup.xyqb.filter;


import cn.quantgroup.xyqb.model.JsonResult;
import cn.quantgroup.xyqb.model.session.SessionStruct;
import cn.quantgroup.xyqb.service.session.ISessionService;
import cn.quantgroup.xyqb.session.XyqbSessionContextHolder;
import com.alibaba.fastjson.JSONObject;
import org.apache.http.HttpStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Objects;

/**
 * Created by 11 on 2016/12/29.
 */
@Component
public class RequestFilter implements Filter {

    /**
     * 带状态
     */
    private static final String[] ALLOWED_PATTERNS = {"/auth/info/login", "/platform/api/page/next"};
    /**
     * 带状态请求鉴权失败时的响应信息
     */
    private static final String UNAUTH_RESULT = JSONObject.toJSONString(JsonResult.buildErrorStateResult("登录失败", null));
    @Autowired
    private ISessionService sessionService;
    private AntPathMatcher matcher = new AntPathMatcher();

    @Override
    public void init(FilterConfig filterConfig) {
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        // 带状态接口
        if (isMatch(request)) {
            // 需获取session信息
            SessionStruct sessionStruct = XyqbSessionContextHolder.getXSessionFromRedis();
            if (Objects.isNull(sessionStruct)) {
        /* 如果没有获取到session信息则返回错误信息 */
                response.setStatus(HttpStatus.SC_UNAUTHORIZED);
                response.setHeader("Content-Type", "application/json;charset=utf-8");
                PrintWriter writer = response.getWriter();
                writer.print(UNAUTH_RESULT);
                writer.close();
                return;
            } else {
        /* 延续session生命期 */
                try {
                    sessionService.persistSession(sessionStruct.getSid(), sessionStruct.getValues());
                } finally {
                    XyqbSessionContextHolder.releaseSession();
                }
            }
        }
        filterChain.doFilter(request, response);
    }

    /**
     * 判断是否带状态请求
     *
     * @param request
     * @return
     */
    private boolean isMatch(HttpServletRequest request) {
        String path = getRequestPath(request);
        for (String pattern : ALLOWED_PATTERNS) {
            if (matcher.match(pattern, path)) {
                return true;
            }
        }
        return false;
    }

    private String getRequestPath(HttpServletRequest request) {
        String url = request.getServletPath();
        if (Objects.nonNull(request.getPathInfo())) {
            url += request.getPathInfo();
        }
        return url;
    }

    @Override
    public void destroy() {

    }
}
