package security.interceptor;

import com.fasterxml.jackson.databind.ObjectMapper;
import common.model.User;
import common.repository.UserRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import security.RedisLoginStatusManager;
import security.TokenManager;
import util.Constant;
import util.ResultModel;
import util.ResultStatus;
import util.StringUtil;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedWriter;
import java.io.OutputStreamWriter;
import java.util.Enumeration;

public class AuthorizationInterceptor extends HandlerInterceptorAdapter {
    private static final Logger logger = LoggerFactory.getLogger(AuthorizationInterceptor.class);
    //存放鉴权信息的Header名称,默认是Authorization
    public static String httpHeaderName = "Authorization";
    @Autowired
    private UserRepository userRepository;

    @Autowired
    private TokenManager manager;
    @Autowired
    private RedisLoginStatusManager redisLoginStatusManager;

    //鉴权信息的无用前缀,默认为空
    private String httpHeaderPrefix = "";
    public void setHttpHeaderName(String httpHeaderName) {
        this.httpHeaderName = httpHeaderName;
    }

    public void setHttpHeaderPrefix(String httpHeaderPrefix) {
        this.httpHeaderPrefix = httpHeaderPrefix;
    }

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        //放开登录

        String requestURL = request.getRequestURL().toString();
        if(requestURL.contains("findSaleInfo")){
            System.out.println("-----"+requestURL.contains("findSaleInfo"));
            return true;
        }
        System.out.println("============="+requestURL);
        System.out.println(requestURL.indexOf("accountmng/findSaleInfo"));
        if (requestURL.indexOf("login/login") != -1
                || requestURL.indexOf("update/pwd") != -1
                || requestURL.indexOf("user/forget") != -1
                || requestURL.indexOf("user/code") != -1
                || requestURL.indexOf("contract/build") != -1
                || requestURL.indexOf("accountmng/findSaleInfo") != -1){
            return true;
        }

        //从header中得到token
        String token = request.getHeader(httpHeaderName);
        //token = StringUtil.isEmpty(token) ? getCookieToken(request.getCookies(), "TOKEN") : token;
        if(null != token){
            token = token.substring(httpHeaderPrefix.length());
            //验证token
            String key = manager.getKeyFromToken(token);
            //登陆状态
            boolean loginStatus = redisLoginStatusManager.getLoginStatusByKey(token);

            if (!StringUtil.isEmpty(key)) {
                User one = userRepository.findOne(Long.parseLong(key));

                User sessionAct = (User) request.getSession().getAttribute(Constant.CURRENT_ACCOUNT);
                if (sessionAct == null) {
                    request.getSession().setAttribute(Constant.CURRENT_ACCOUNT,one);
                }
                return true;
            }
        }

        try {
            //如果验证token失败,并且方法注明了Authorization,返回401错误
            response.setStatus(HttpStatus.UNAUTHORIZED.value());
            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(response.getOutputStream()));
            response.setContentType(MediaType.APPLICATION_JSON_VALUE);
            String json = new ObjectMapper().writeValueAsString(ResultModel.ERROR(ResultStatus.USERNAME_LOGIN_EXPIRE));
            writer.write(json);
            writer.close();
        } catch (Exception e){
            e.printStackTrace();
        }
        return false;
    }

    private String getCookieToken(Cookie[] cookies, String name){

        String token = null;

        if (null != cookies) {
            for (Cookie cookie : cookies) {
                if (cookie.getName().equals(name)) {
                    token = cookie.getValue();
                }
            }
        }

        return token;
    }
}