package dev.inmo.postssystem.features.roles.client

import dev.inmo.postssystem.features.roles.common.*
import dev.inmo.micro_utils.ktor.client.UnifiedRequester
import dev.inmo.micro_utils.ktor.common.buildStandardUrl
import kotlinx.serialization.KSerializer
import kotlinx.serialization.builtins.ListSerializer
import kotlinx.serialization.builtins.serializer

class ReadClientRolesStorage<T : Role>(
    private val baseUrl: String,
    private val unifiedRequester: UnifiedRequester,
    private val serializer: KSerializer<T>
) : ReadRolesStorage<T> {
    private val userRolesSerializer = ListSerializer(serializer)

    private val userRolesFullUrl = buildStandardUrl(
        baseUrl,
        usersRolesRootPathPart
    )

    override suspend fun getSubjects(
        role: T
    ): List<RoleSubject> = unifiedRequester.uniget(
        buildStandardUrl(
            userRolesFullUrl,
            usersRolesGetSubjectsPathPart,
            usersRolesRoleQueryParameterName to unifiedRequester.encodeUrlQueryValue(serializer, role)
        ),
        RoleSubjectsSerializer
    )

    override suspend fun getRoles(
        subject: RoleSubject
    ): List<T> = unifiedRequester.uniget(
        buildStandardUrl(
            userRolesFullUrl,
            usersRolesGetRolesPathPart,
            usersRolesRoleSubjectQueryParameterName to unifiedRequester.encodeUrlQueryValue(RoleSubject.serializer(), subject)
        ),
        userRolesSerializer
    )

    override suspend fun contains(
        subject: RoleSubject,
        role: T
    ): Boolean = unifiedRequester.uniget(
        buildStandardUrl(
            userRolesFullUrl,
            usersRolesContainsPathPart,
            usersRolesRoleSubjectQueryParameterName to unifiedRequester.encodeUrlQueryValue(RoleSubject.serializer(), subject),
            usersRolesRoleQueryParameterName to unifiedRequester.encodeUrlQueryValue(serializer, role)
        ),
        Boolean.serializer()
    )

    override suspend fun containsAny(
        subject: RoleSubject,
        roles: List<T>
    ): Boolean = unifiedRequester.uniget(
        buildStandardUrl(
            userRolesFullUrl,
            usersRolesContainsAnyPathPart,
            usersRolesRoleSubjectQueryParameterName to unifiedRequester.encodeUrlQueryValue(RoleSubject.serializer(), subject),
            usersRolesRoleQueryParameterName to unifiedRequester.encodeUrlQueryValue(userRolesSerializer, roles)
        ),
        Boolean.serializer()
    )
}
