package com.patzn.lims.config;

import com.baomidou.kisso.SSOHelper;
import com.baomidou.kisso.annotation.Action;
import com.baomidou.kisso.annotation.Login;
import com.baomidou.kisso.common.util.HttpUtil;
import com.baomidou.kisso.web.interceptor.SSOSpringInterceptor;
import com.patzn.lims.core.web.Account;
import com.patzn.lims.core.web.LoginHandlerInterceptor;
import com.patzn.lims.core.web.LoginHelper;
import com.patzn.lims.core.web.PtConfigurer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;


/**
 * <p>
 * WEB 初始化相关配置
 * </p>
 *
 * @author hubin
 * @since 2019-03-13
 */
@Slf4j
@ControllerAdvice
@Configuration
public class WebConfigurer extends PtConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // SSO 授权拦截器
        SSOSpringInterceptor ssoInterceptor = new SSOSpringInterceptor() {

            @Override
            public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
                    throws Exception {
                /**
                 * 处理 Controller 方法
                 * <p>
                 * 判断 handler 是否为 HandlerMethod 实例
                 * </p>
                 */
                if (handler instanceof HandlerMethod) {
                    HandlerMethod handlerMethod = (HandlerMethod) handler;
                    Method method = handlerMethod.getMethod();
                    Login login = method.getAnnotation(Login.class);
                    if (login != null) {
                        if (login.action() == Action.Skip) {
                            /**
                             * 忽略拦截
                             */
                            return true;
                        }
                    }

                    /**
                     * 正常执行
                     */
                    Account account = LoginHelper.getAccount(request, false);
                    if (account == null) {
                        if (HttpUtil.isAjax(request)) {
                            /*
                             * Handler 处理 AJAX 请求
                             */
                            this.getHandlerInterceptor().preTokenIsNullAjax(request, response);
                            return false;
                        } else {
                            /*
                             * token 为空，调用 Handler 处理
                             * 返回 true 继续执行，清理登录状态并重定向至登录界面
                             */
                            if (this.getHandlerInterceptor().preTokenIsNull(request, response)) {
                                log.debug("logout. request url:" + request.getRequestURL());
                                SSOHelper.clearRedirectLogin(request, response);
                            }
                            return false;
                        }
                    }
                }

                /**
                 * 通过拦截
                 */
                return true;
            }
        };
        ssoInterceptor.setHandlerInterceptor(new LoginHandlerInterceptor());
        registry.addInterceptor(ssoInterceptor).addPathPatterns("/**");
    }

    /**
     * 用户加密方式
     */
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}
