package security.interceptor;

import com.fasterxml.jackson.databind.ObjectMapper;
import common.model.Auth;
import common.model.User;
import common.repository.AuthRepository;
import common.repository.UserRepository;
import dic.RoleEnum;
import net.sf.json.JSONArray;
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.util.StringUtils;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import security.RedisLoginStatusManager;
import security.TokenManager;
import security.annotation.AuthKey;
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;
import java.util.Map;
import java.util.stream.Collectors;

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 AuthRepository authRepository;

    @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("txt2db") != -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 sessionAct = (User) request.getSession().getAttribute(Constant.CURRENT_ACCOUNT);
                // 可这里查出权限
                if (sessionAct == null) {
                    User one = userRepository.findOne(Long.parseLong(key));

                    if (!one.getRole().equals(RoleEnum.MANAGER.getKey())) {
                        Auth auth = authRepository.findByUser(one.getId());
                        Map<String, String> authdata = (Map<String, String>) JSONArray.fromObject(auth.getAuth())
                                .stream().collect(Collectors.toMap(p -> ((Map) p).get("id").toString(), p -> "0"));
                        one.setAuthdataDic(authdata);
                    }

                    request.getSession().setAttribute(Constant.CURRENT_ACCOUNT,one);
                    sessionAct = one;
                }

                if(!sessionAct.getRole().equals(RoleEnum.MANAGER.getKey())){
                    //权限控制
                    AuthKey authKey =  handler.getClass().getAnnotation(AuthKey.class);
                    if(authKey!=null && sessionAct.getAuthdataDic().get(authKey.value().getIdKey())==null){
                        printJsonResponse(response,"权限不足!");
                        return false;
                    }

                    return true;
                }

                return true;
            }

        }

        printJsonResponse(response,null);

        return false;
    }

    private void printJsonResponse(HttpServletResponse response,String message){
        try {
            //如果验证token失败，并且方法注明了Authorization，返回401错误
            response.setStatus(HttpStatus.UNAUTHORIZED.value());
            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(response.getOutputStream()));
            response.setContentType(MediaType.APPLICATION_JSON_VALUE);

            if(StringUtils.isEmpty(message)){
                message = new ObjectMapper().writeValueAsString(ResultModel.ERROR(ResultStatus.USERNAME_LOGIN_EXPIRE));
            }

            writer.write(message);
            writer.close();
        } catch (Exception e){
            e.printStackTrace();
        }
    }


    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;
    }
}