package com.cretin.webservices.interceptor

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper
import com.cretin.webcore.exception.WholeException
import com.cretin.webcore.helper.SpringContextUtil
import com.cretin.webcore.utils.IpUtils
import com.cretin.webdb.entity.TbStrTranslateUser
import com.cretin.webdb.entity.TbV2HandleLog
import com.cretin.webdb.service.ITbStrTranslateUserService
import com.cretin.webdb.service.ITbV2HandleLogService
import com.cretin.webredis.RedisUtils
import org.apache.http.util.TextUtils
import org.springframework.web.servlet.HandlerInterceptor
import org.springframework.web.servlet.ModelAndView
import java.io.UnsupportedEncodingException
import java.lang.Exception
import java.net.URLDecoder
import java.time.LocalDateTime
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse

class AuthenticationInterceptor : HandlerInterceptor {

    private val WHITE_LIST_CONTAINS = mutableSetOf<String>().apply {
        add("admin/translate/user/login")
        add("v2/desktop/translate/login")
        add("translate/getpiccode")
        add("translate/getcode")
        add("translate/user/register")
        add("/app/info")
    }

    private val WHITE_LIST_EQUALS = mutableSetOf<String>().apply {
        add("/")
        add("/error")
    }

    private val logService by lazy {
        SpringContextUtil.getBean(ITbV2HandleLogService::class.java)
    }

    private val userService by lazy {
        SpringContextUtil.getBean(ITbStrTranslateUserService::class.java)
    }


    override fun preHandle(request: HttpServletRequest, response: HttpServletResponse, handler: Any): Boolean {
        UserContextHolder.setIp(IpUtils.getIpAddr(request))
        val path = request.servletPath
        for (whiteListContain in WHITE_LIST_CONTAINS) {
            if (path.contains(whiteListContain)) {
                return true
            }
        }
        for (whiteListContain in WHITE_LIST_EQUALS) {
            if (path == whiteListContain) {
                return true
            }
        }
        val token = request.getHeader("token")
        if (TextUtils.isEmpty(token)) {
            throw WholeException(201, "请输入正确的登录令牌")
        }
        val userQueryWrapper = QueryWrapper<TbStrTranslateUser>()
        userQueryWrapper.eq("token", token)
        val user = userService?.getOne(userQueryWrapper, false) ?: throw WholeException(201, "请输入正确的登录令牌")
        if (user.status != 0) throw WholeException(201, "当前登录令牌已被限制使用")
        UserContextHolder.setUserInfo(user)
        return true
    }

    override fun postHandle(
        request: HttpServletRequest,
        response: HttpServletResponse,
        handler: Any,
        modelAndView: ModelAndView?
    ) {
        logService?.save(TbV2HandleLog().apply {
            this.ip = UserContextHolder.getIp() ?: "unknown"
            this.userId = UserContextHolder.getUserInfo()?.id ?: -1000
            this.requestUrl = request?.servletPath ?: ""
            this.addTime = LocalDateTime.now()
        })
    }

    override fun afterCompletion(
        request: HttpServletRequest,
        response: HttpServletResponse,
        handler: Any,
        ex: Exception?
    ) {
        UserContextHolder.clear()
    }
}