summaryrefslogtreecommitdiff
path: root/src/main/kotlin/io/dico/parcels2/Privilege.kt
blob: bc16f77bb524a7644cbb7edb8bf6d984e44c5927 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
package io.dico.parcels2

import io.dico.parcels2.Privilege.DEFAULT
import java.util.Collections

typealias PrivilegeKey = PlayerProfile.Real
typealias PrivilegeMap = Map<PrivilegeKey, Privilege>
typealias MutablePrivilegeMap = MutableMap<PrivilegeKey, Privilege>

@Suppress("FunctionName")
fun MutablePrivilegeMap(): MutablePrivilegeMap = hashMapOf()

@Suppress("UNCHECKED_CAST")
val EmptyPrivilegeMap = Collections.emptyMap<Any, Any>() as MutablePrivilegeMap

enum class Privilege(
    val number: Int,
    val transient: Boolean = false
) {
    BANNED(1),
    DEFAULT(2),
    CAN_BUILD(3),
    CAN_MANAGE(4),

    OWNER(-1, transient = true),
    ADMIN(-1, transient = true);

    fun isDistanceGrEq(other: Privilege): Boolean =
        when {
            other > DEFAULT -> this >= other
            other == DEFAULT -> this == other
            else -> this <= other
        }

    fun isChangeInDirection(positiveDirection: Boolean, update: Privilege): Boolean =
        if (positiveDirection) update > this
        else update < this

    fun requireNonTransient(): Privilege {
        if (transient) {
            throw IllegalArgumentException("Transient privilege $this is invalid")
        }
        return this
    }

    companion object {
        fun getByNumber(id: Int) =
            when (id) {
                1 -> BANNED
                2 -> DEFAULT
                3 -> CAN_BUILD
                4 -> CAN_MANAGE
                else -> null
            }
    }
}

interface RawPrivileges {
    val privilegeMap: PrivilegeMap
    var privilegeOfStar: Privilege

    fun getRawStoredPrivilege(key: PrivilegeKey): Privilege
    fun setRawStoredPrivilege(key: PrivilegeKey, privilege: Privilege): Boolean
}

open class PrivilegesHolder(override var privilegeMap: MutablePrivilegeMap = EmptyPrivilegeMap) : RawPrivileges {
    private var _privilegeOfStar: Privilege = DEFAULT

    override var privilegeOfStar: Privilege
        get() = _privilegeOfStar
        set(value) = run { _privilegeOfStar = value }

    protected val isEmpty
        inline get() = privilegeMap === EmptyPrivilegeMap

    override fun getRawStoredPrivilege(key: PrivilegeKey) =
        if (key.isStar) _privilegeOfStar
        else privilegeMap.getOrDefault(key, _privilegeOfStar)

    override fun setRawStoredPrivilege(key: PrivilegeKey, privilege: Privilege): Boolean {
        privilege.requireNonTransient()

        if (key.isStar) {
            if (_privilegeOfStar == privilege) return false
            _privilegeOfStar = privilege
            return true
        }

        if (isEmpty) {
            if (privilege == DEFAULT) return false
            privilegeMap = MutablePrivilegeMap()
        }

        return if (privilege == DEFAULT) privilegeMap.remove(key) != null
        else privilegeMap.put(key, privilege) != privilege
    }
}