package com.dmdirc.ktirc.model import com.dmdirc.ktirc.io.CaseMapping import kotlin.reflect.KClass class ServerState(initialNickname: String) { var localNickname: String = initialNickname val features = ServerFeatureMap() } class ServerFeatureMap { private val features = HashMap, Any?>() @Suppress("UNCHECKED_CAST") operator fun get(feature: ServerFeature) = features.getOrDefault(feature, feature.default) as? T? ?: feature.default operator fun set(feature: ServerFeature<*>, value: Any) { require(feature.type.isInstance(value)) features[feature] = value } fun setAll(featureMap: ServerFeatureMap) = featureMap.features.forEach { feature, value -> features[feature] = value } fun reset(feature: ServerFeature<*>) = features.put(feature, null) } sealed class ServerFeature(val name: String, val type: KClass, val default: T? = null) { object ServerCaseMapping : ServerFeature("CASEMAPPING", CaseMapping::class, CaseMapping.Rfc) object MaximumChannels : ServerFeature("CHANLIMIT", Int::class) object ChannelModes : ServerFeature("CHANMODES", String::class) object MaximumChannelNameLength : ServerFeature("CHANNELLEN", Int::class, 200) object WhoxSupport : ServerFeature("WHOX", Boolean::class, false) } val serverFeatures: Map> by lazy { ServerFeature::class.nestedClasses.map { it.objectInstance as ServerFeature<*> }.associateBy { it.name } }