package com.dmdirc.ktirc.state import com.dmdirc.ktirc.io.CaseMapping import kotlin.reflect.KClass interface ServerState { var localNickname: String fun getFeature(feature: ServerFeature): T? fun setFeature(feature: ServerFeature<*>, value: Any) fun resetFeature(feature: ServerFeature<*>): Any? } class IrcServerState(initialNickname: String) : ServerState { override var localNickname: String = initialNickname private val features = HashMap, Any>() @Suppress("UNCHECKED_CAST") override fun getFeature(feature: ServerFeature) = features.getOrDefault(feature, feature.default) as? T? override fun setFeature(feature: ServerFeature<*>, value: Any) { require(feature.type.isInstance(value)) features[feature] = value } override fun resetFeature(feature: ServerFeature<*>) = features.remove(feature) } 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) } val serverFeatures: Map> by lazy { ServerFeature::class.nestedClasses.map { it.objectInstance as ServerFeature<*> }.associateBy { it.name } }