package com.inkasso.auth.interceptor;


import com.inkasso.adapter.bean.AbstractUser;
import com.inkasso.adapter.exception.ServiceException;
import com.inkasso.adapter.web.LoginUserHolder;
import com.inkasso.auth.enums.AuthTypeEnum;
import com.inkasso.auth.service.AbstractAuthentication;
import com.inkasso.auth.service.AuthenticationTypeService;
import org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController;
import org.springframework.util.CollectionUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;

/**
 * @author 张超
 * @date 2021/10/19
 */
public class AuthenticationInterceptor extends AuthenticationTypeService implements
        HandlerInterceptor {

    private String bankendPackageName = "com.inkasso.factoring.login";

    private final String mark = "*";

    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest,
                             HttpServletResponse httpServletResponse, Object o) {

        if (!(o instanceof HandlerMethod)) {
            return true;
        }
        if (o instanceof HandlerMethod) {
            HandlerMethod hm = (HandlerMethod) o;
            if (((HandlerMethod) o).getBean() instanceof BasicErrorController) {
                return true;
            }

        }
        String uri = httpServletRequest.getRequestURI();
        uri = uri.substring(1);
        if (comparePath(uri, super.getWhiteUrl()) && !uri.equals("fastassess/fastassess/report")) {
            //标识请求的路径在白名单里面 可以直接通过
            return true;
        }
        HandlerMethod hm = (HandlerMethod) o;
        AbstractUser abstractUser = null;
        String packageName = hm.getBean().getClass().getPackage().getName();
        //判断  如果是  特定包下面的  则需要 用另外一个 认证流程
        String model = null;
        if (packageName.contains(bankendPackageName)) {
            model = AuthTypeEnum.BACKEND_USER.getCode();
        } else {
            model = AuthTypeEnum.TOKEN.getCode();
        }
        //如果不在白名单中需要认证 第一步获得认证模式
        //   String model = httpServletRequest.getHeader(AuthConstance.X_AUTH_TYPE);
//    if (StringUtils.isBlank(model)) {
//      throw new ServiceException(400, "认证模式错误");
//    }
        AbstractAuthentication abstractAuthentication = getByType(model);
        if (abstractAuthentication == null) {
            throw new ServiceException(400, "认证模式错误");
        }
        abstractUser = abstractAuthentication.auth(httpServletRequest);
        if (abstractUser == null) {
            throw new ServiceException(401, "用户信息不存在,请重新登陆");
        }
        LoginUserHolder.clear();
        LoginUserHolder.set(abstractUser);
        return true;
    }


    /*
     * 比较用户能否
     * */
    public boolean comparePath(String path, List<String> list) {
        if (CollectionUtils.isEmpty(list)) {
            return false;
        }
        String[] paths = path.split("/");
        for (String r : list) {
            String[] urls = r.split("/");
            if (paths.length != urls.length) {
                continue;
            }
            //每一段的路径匹配
            for (int i = 0; i < paths.length; i++) {
                if (!(mark.equals(urls[i]) || paths[i].equals(urls[i]))) {
                    break;
                }
                if (i + 1 == paths.length) {
                    //校验成功
                    return true;
                }
            }
        }
        return false;
    }


}
