package com.nokia.service;

import com.nokia.dao.UserDao;
import com.nokia.pojo.User;
import com.nokia.vo.TokenFlagVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class AclService {

    @Value("${redis.timeoutSeconds:600}")
    private Integer timeoutSeconds;

    private final UserDao userDao;
    private final TopService topService;
    private final DopService dopService;

    private final RedisTemplate<String, Object> redisTemplate;

    @Autowired
    public AclService(UserDao userDao, TopService topService, DopService dopService,
            RedisTemplate<String, Object> redisTemplate) {
        this.userDao = userDao;
        this.topService = topService;
        this.dopService = dopService;
        this.redisTemplate = redisTemplate;
    }

    public User verifySystem(String token, String fromSystem) {
        User userEntity = null;
        // 从redis中查询
        userEntity = (User) redisTemplate.opsForValue().get(token);
        if (userEntity != null) {
            log.debug("redis查询成功: {}", userEntity);
            // 2.1 可以查到用户信息，重置redis中的用户信息，刷新到期时间
            redisTemplate.opsForValue().set(token, userEntity, timeoutSeconds, TimeUnit.SECONDS);
            // 3 返回用户信息
            return userEntity;
        } else {
            // 2.2 无法查到用户信息 可能是已超timeoutSeconds或者是初次登录
            // 需要根据fromSystem参数去对应的系统进行鉴权
            TokenFlagVo tokenFlagVo = getVerifyResult(token, fromSystem);
            if (tokenFlagVo != null && tokenFlagVo.isValid()) {
                // 如果token状态为可用，根据loginName从数据库查询用户
                // 这里存在一个问题，如果是在top已存在的用户，但是我们系统没有，此时返回的userEntity为null，会对后续处理产生影响，需要考虑应该怎么做
                // 在前端处理，上面的问题仅影响初次点击入口的用户，不影响超时用户
                // 前端需要对入口用户做特别的处理
                userEntity = userDao.getByLoginName(tokenFlagVo.getLoginName());
                if (userEntity != null) {
                    // 仅当用户信息不为空时,将用户信息存入redis
                    redisTemplate.opsForValue().set(token, userEntity, timeoutSeconds, TimeUnit.SECONDS);
                }
                // 返回用户信息
                return userEntity;
            } else {
                // token无效,返回重定向的登陆地址
                return null;
            }
        }
    }

    private TokenFlagVo getVerifyResult(String token, String fromSystem) {
        if (fromSystem.trim().equalsIgnoreCase("dop")) {
            return dopService.dopReturn(token);
        } else if (fromSystem.trim().equalsIgnoreCase("top")) {
            return topService.topReturn(token);
        } else if (fromSystem.trim().equalsIgnoreCase("test")) {
            // 测试用
            return testToken(token);
        }
        return null;
    }

    private TokenFlagVo testToken(String token) {
        String login_name = token.trim().toLowerCase();
        login_name = login_name.replace("test_token_", "test_");
        return new TokenFlagVo(0, login_name);
    }
}
