package rd.service.auth;

import cn.dev33.satoken.stp.StpInterface;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import lombok.extern.slf4j.Slf4j;
import rd.data.db.table.UserBasic;
import rd.data.enums.UserType;
import rd.service.user.UserBasicService;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class UserTypeStpInterfaceImpl implements StpInterface {
    private static final Cache<Long, List<String>> userRoleCache = Caffeine.newBuilder()
            .expireAfterAccess(15, TimeUnit.DAYS)
            .initialCapacity(256)
            .maximumSize(2048)
            .build();

    private static final List<String> EMPTY_ARRAY = List.of();

    private final UserBasicService userBasicService;

    public UserTypeStpInterfaceImpl(UserBasicService userBasicService) {
        this.userBasicService = userBasicService;
    }

    @Override
    public List<String> getPermissionList(Object uid, String loginType) {
        List<String> permissions = new ArrayList<>();
        permissions.add("all");

        return permissions;
    }

    @Override
    public List<String> getRoleList(Object uid, String loginType) {
        Long longUid;
        if (uid instanceof String sUid) {
            longUid = Long.valueOf(sUid);
        } else if (uid instanceof Long lUid) {
            longUid = lUid;
        } else {
            throw new RuntimeException();
        }

        List<String> roles = userRoleCache.getIfPresent(longUid);
        if (roles != null) {
            return roles;
        } else {
            roles = new ArrayList<>(1);
        }

        UserBasic userBasic = userBasicService.getUserBasicById(longUid);
        if (userBasic == null) {
            return EMPTY_ARRAY;
        }

        roles.add(switch (userBasic.getType()) {
            case 0 -> UserType.STUDENT.name();
            case 1 -> UserType.TEACHER.name();
            case 2 -> UserType.ADMIN.name();
            default -> {
                log.warn("未知的用户类型：{}", userBasic.getType());
                yield UserType.STUDENT.name();
            }
        });

        if (userBasic.getType().intValue() == UserType.ADMIN.code) {
            roles.add(UserType.TEACHER.name());
            roles.add(UserType.STUDENT.name());
        }

        userRoleCache.put(longUid, roles);
        return roles;
    }
}
