{{^multiplatform}}
{{#gson}}
import com.google.gson.annotations.SerializedName
{{/gson}}
{{#moshi}}
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
{{/moshi}}
{{#jackson}}
{{#enumUnknownDefaultCase}}
import com.fasterxml.jackson.annotation.JsonEnumDefaultValue
{{/enumUnknownDefaultCase}}
import com.fasterxml.jackson.annotation.JsonProperty
{{/jackson}}
{{#kotlinx_serialization}}
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
{{#enumUnknownDefaultCase}}
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializer
import kotlinx.serialization.builtins.serializer
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
{{/enumUnknownDefaultCase}}
{{/kotlinx_serialization}}
{{/multiplatform}}
{{#multiplatform}}
import kotlinx.serialization.*
{{/multiplatform}}

/**
 * {{{description}}}
 *
 * Values: {{#allowableValues}}{{#enumVars}}{{&name}}{{^-last}},{{/-last}}{{/enumVars}}{{/allowableValues}}
 */
{{#multiplatform}}@Serializable{{/multiplatform}}{{#kotlinx_serialization}}@Serializable{{#enumUnknownDefaultCase}}(with = {{classname}}Serializer::class){{/enumUnknownDefaultCase}}{{/kotlinx_serialization}}
{{^multiplatform}}
{{#moshi}}
@JsonClass(generateAdapter = false)
{{/moshi}}
{{/multiplatform}}
{{#nonPublicApi}}internal {{/nonPublicApi}}{{^nonPublicApi}}public {{/nonPublicApi}}enum class {{classname}}(public val value: {{{dataType}}}) {
{{#allowableValues}}{{#enumVars}}
    {{^multiplatform}}
    {{#moshi}}
    @Json(name = {{#lambda.doublequote}}{{{value}}}{{/lambda.doublequote}})
    {{/moshi}}
    {{#gson}}
    @SerializedName(value = {{#lambda.doublequote}}{{{value}}}{{/lambda.doublequote}})
    {{/gson}}
    {{#jackson}}
    @JsonProperty(value = {{#lambda.doublequote}}{{{value}}}{{/lambda.doublequote}}){{#enumUnknownDefaultCase}}{{#-last}} @JsonEnumDefaultValue{{/-last}}{{/enumUnknownDefaultCase}}
    {{/jackson}}
    {{#kotlinx_serialization}}
    @SerialName(value = {{#lambda.doublequote}}{{{value}}}{{/lambda.doublequote}})
    {{/kotlinx_serialization}}
    {{/multiplatform}}
    {{#multiplatform}}
    @SerialName(value = {{#lambda.doublequote}}{{{value}}}{{/lambda.doublequote}})
    {{/multiplatform}}
    {{#isArray}}
    {{#isList}}
    {{&name}}(listOf({{{value}}})){{^-last}},{{/-last}}{{#-last}};{{/-last}}
    {{/isList}}
    {{^isList}}
    {{&name}}(arrayOf({{{value}}})){{^-last}},{{/-last}}{{#-last}};{{/-last}}
    {{/isList}}
    {{/isArray}}
    {{^isArray}}
    {{&name}}({{{value}}}){{^-last}},{{/-last}}{{#-last}};{{/-last}}
    {{/isArray}}
{{/enumVars}}{{/allowableValues}}
    /**
     * Override [toString()] to avoid using the enum variable name as the value, and instead use
     * the actual value defined in the API spec file.
     *
     * This solves a problem when the variable name and its value are different, and ensures that
     * the client sends the correct enum values to the server always.
     */
    override fun toString(): kotlin.String = value{{^isString}}.toString(){{/isString}}

    {{^nonPublicApi}}public {{/nonPublicApi}}companion object {
        /**
         * Converts the provided [data] to a [String] on success, null otherwise.
         */
        {{^nonPublicApi}}public {{/nonPublicApi}}fun encode(data: kotlin.Any?): kotlin.String? = if (data is {{classname}}) "$data" else null

        /**
         * Returns a valid [{{classname}}] for [data], null otherwise.
         */
        {{^nonPublicApi}}public {{/nonPublicApi}}fun decode(data: kotlin.Any?): {{classname}}? = data?.let {
          val normalizedData = "$it".lowercase()
          values().firstOrNull { value ->
            it == value || normalizedData == "$value".lowercase()
          }
        }
    }
}{{#kotlinx_serialization}}{{#enumUnknownDefaultCase}}

@Serializer(forClass = {{classname}}::class)
internal object {{classname}}Serializer : KSerializer<{{classname}}> {
    override val descriptor = {{{dataType}}}.serializer().descriptor

    override fun deserialize(decoder: Decoder): {{classname}} {
        val value = decoder.decodeSerializableValue({{{dataType}}}.serializer())
        return {{classname}}.values().firstOrNull { it.value == value }
            ?: {{classname}}.{{#allowableValues}}{{#enumVars}}{{#-last}}{{&name}}{{/-last}}{{/enumVars}}{{/allowableValues}}
    }

    override fun serialize(encoder: Encoder, value: {{classname}}) {
        encoder.encodeSerializableValue({{{dataType}}}.serializer(), value.value)
    }
}{{/enumUnknownDefaultCase}}{{/kotlinx_serialization}}
