package dev.inmo.postssystem.features.roles.server

import dev.inmo.postssystem.features.roles.common.*
import dev.inmo.micro_utils.common.*
import kotlin.reflect.KClass

data class RolesStorageHolder<T : Role>(
    val kclass: KClass<T>,
    val storage: RolesStorage<T>
) {
    private suspend fun <R> doIfRelevant(
        role: Role,
        block: suspend (T) -> R
    ): Optional<R> = if (kclass.isInstance(role)) {
        block(role as T).optional
    } else {
        Optional.absent()
    }

    suspend fun getUsers(role: Role): List<RoleSubject>? = doIfRelevant(role) {
        storage.getSubjects(it)
    }.dataOrNull()

    suspend fun getRoles(subject: RoleSubject): List<Role> = storage.getRoles(subject)

    suspend fun contains(subject: RoleSubject, role: Role): Boolean? = doIfRelevant(role) {
        storage.contains(subject, it)
    }.dataOrNull()

    suspend fun include(
        subject: RoleSubject,
        role: Role
    ): Boolean? = doIfRelevant(role) {
        storage.include(subject, it)
    }.dataOrNull()

    suspend fun exclude(subject: RoleSubject, role: Role): Boolean? = doIfRelevant(role) {
        storage.exclude(subject, it)
    }.dataOrNull()
}
