package pro.shushi.pamirs.thirdparty.core.role;

import org.apache.commons.collections4.CollectionUtils;
import org.springframework.core.annotation.Order;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import pro.shushi.pamirs.auth.api.model.AuthRole;
import pro.shushi.pamirs.auth.api.runtime.spi.impl.DefaultCurrentRolesCache;
import pro.shushi.pamirs.meta.annotation.fun.extern.Slf4j;
import pro.shushi.pamirs.meta.api.session.PamirsSession;
import pro.shushi.pamirs.meta.common.spi.SPI;
import pro.shushi.pamirs.meta.common.spring.BeanDefinitionUtils;
import pro.shushi.pamirs.meta.util.JsonUtils;
import pro.shushi.pamirs.user.api.enmu.UserSourceEnum;
import pro.shushi.pamirs.user.api.login.UserInfoCache;
import pro.shushi.pamirs.user.api.model.PamirsUser;

import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@Slf4j
@SPI.Service
@Component
@Order(1)
public class ThirdPartyRoleCustom extends DefaultCurrentRolesCache {

    public static final String DEMO_ROLE_KEY = "demo:auth:role:";
    public static final int REDIS_EXPIRE_TIME = 3600 * 1;//unit:s
    public static final String THIRD_PARTY_USER_ROLE_CODE = "THIRD_PARTY_USER";// 约定好的角色code(根据实际情况修改)

    @Override
    public Set<Long> get() {
        Set<Long> roleIds = super.get();
        if (CollectionUtils.isEmpty(roleIds)) {
            roleIds = new HashSet<>();
        }
        AuthRole role = fetchTpRole();
        if (role != null) {
            roleIds.add(role.getId());
        }

        return roleIds;
    }

    public AuthRole fetchTpRole() {
        Long userId = PamirsSession.getUserId();
        if (null == userId) {
            return null;
        }

        PamirsUser pamirsUser = UserInfoCache.queryUserById(userId);
        if (UserSourceEnum.THIRD_PARTY.equals(pamirsUser.getSource())) {
            AuthRole role = queryRoleByCode(THIRD_PARTY_USER_ROLE_CODE);
            if (role != null) {
                return role;
            }
        }

        return null;
    }

    private AuthRole queryRoleByCode(String code) {
        StringRedisTemplate redisTemplate = BeanDefinitionUtils.getBean(StringRedisTemplate.class);
        String roleCacheKey = DEMO_ROLE_KEY + code;

        AuthRole role = null;
        String roleJson = redisTemplate.opsForValue().get(roleCacheKey);
        if (!ObjectUtils.isEmpty(roleJson)) {
            role = JsonUtils.parseObject(roleJson, AuthRole.class);
        } else {
            role = new AuthRole().setCode(code).queryOne();
            if (role != null) {
                // 将role放入到缓存中
                redisTemplate.opsForValue().set(roleCacheKey, JsonUtils.toJSONString(role), REDIS_EXPIRE_TIME, TimeUnit.SECONDS);
            }
        }

        return role;
    }

}
