// Generated by alef. Do not edit by hand.
@file:Suppress(
    "ktlint:standard:trailing-comma-on-call-site",
    "ktlint:standard:trailing-comma-on-declaration-site",
    "ktlint:standard:spacing-between-declarations-with-comments",
    "ktlint:standard:spacing-between-declarations-with-annotations",
    "ktlint:standard:when-entry-bracing",
    "ktlint:standard:blank-line-between-when-conditions",
    "ktlint:standard:blank-line-before-declaration",
    "ktlint:standard:chain-method-continuation",
    "ktlint:standard:annotation",
    "ktlint:standard:max-line-length",
    "ktlint:standard:no-semi",
    "ktlint:standard:statement-wrapping",
    "MaxLineLength",
    "TooManyFunctions",
    "FunctionParameterNaming",
    "LongParameterList",
    "CyclomaticComplexMethod",
    "LongMethod",
)

package dev.kreuzberg

/** Best-effort document location for a revision. */
@com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = RevisionAnchorDeserializer::class)
@com.fasterxml.jackson.databind.annotation.JsonSerialize(using = RevisionAnchorSerializer::class)
sealed class RevisionAnchor {
    /** Body paragraph, identified by its zero-based index in the document flow. */
    @com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = com.fasterxml.jackson.databind.JsonDeserializer.None::class)
    @com.fasterxml.jackson.databind.annotation.JsonSerialize(using = com.fasterxml.jackson.databind.JsonSerializer.None::class)
    data class Paragraph(
        val index: Long,
    ) : RevisionAnchor()
    /** Cell inside a table. */
    @com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = com.fasterxml.jackson.databind.JsonDeserializer.None::class)
    @com.fasterxml.jackson.databind.annotation.JsonSerialize(using = com.fasterxml.jackson.databind.JsonSerializer.None::class)
    data class TableCell(
        val row: Long,
        val col: Long,
        val tableIndex: Long,
    ) : RevisionAnchor()
    /** Page, identified by its zero-based index. */
    @com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = com.fasterxml.jackson.databind.JsonDeserializer.None::class)
    @com.fasterxml.jackson.databind.annotation.JsonSerialize(using = com.fasterxml.jackson.databind.JsonSerializer.None::class)
    data class Page(
        val index: Long,
    ) : RevisionAnchor()
    /** Presentation slide, identified by its zero-based index. */
    @com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = com.fasterxml.jackson.databind.JsonDeserializer.None::class)
    @com.fasterxml.jackson.databind.annotation.JsonSerialize(using = com.fasterxml.jackson.databind.JsonSerializer.None::class)
    data class Slide(
        val index: Long,
    ) : RevisionAnchor()
    /** Spreadsheet cell or range, identified by sheet index and optional name. */
    @com.fasterxml.jackson.databind.annotation.JsonDeserialize(using = com.fasterxml.jackson.databind.JsonDeserializer.None::class)
    @com.fasterxml.jackson.databind.annotation.JsonSerialize(using = com.fasterxml.jackson.databind.JsonSerializer.None::class)
    data class Sheet(
        val index: Long,
        val name: String?,
    ) : RevisionAnchor()
}

private class RevisionAnchorDeserializer : com.fasterxml.jackson.databind.deser.std.StdDeserializer<RevisionAnchor>(RevisionAnchor::class.java) {
    @Suppress("LongMethod")
    override fun deserialize(
        parser: com.fasterxml.jackson.core.JsonParser,
        ctx: com.fasterxml.jackson.databind.DeserializationContext,
    ): RevisionAnchor {
        val node = parser.codec.readTree<com.fasterxml.jackson.databind.node.ObjectNode>(parser)
        val tag = node.get("type")?.asText()
        @Suppress("UNCHECKED_CAST")
        val payload = (node.deepCopy() as com.fasterxml.jackson.databind.node.ObjectNode).apply { remove("type") }
        return when (tag) {
            "paragraph" -> ctx.readTreeAsValue<RevisionAnchor.Paragraph>(payload, RevisionAnchor.Paragraph::class.java)
            "table_cell" -> ctx.readTreeAsValue<RevisionAnchor.TableCell>(payload, RevisionAnchor.TableCell::class.java)
            "page" -> ctx.readTreeAsValue<RevisionAnchor.Page>(payload, RevisionAnchor.Page::class.java)
            "slide" -> ctx.readTreeAsValue<RevisionAnchor.Slide>(payload, RevisionAnchor.Slide::class.java)
            "sheet" -> ctx.readTreeAsValue<RevisionAnchor.Sheet>(payload, RevisionAnchor.Sheet::class.java)
            else -> throw com.fasterxml.jackson.databind.exc.InvalidFormatException(
                parser, "Unknown RevisionAnchor tag", tag, RevisionAnchor::class.java,
            )
        }
    }
}

private class RevisionAnchorSerializer : com.fasterxml.jackson.databind.ser.std.StdSerializer<RevisionAnchor>(RevisionAnchor::class.java) {
    @Suppress("LongMethod")
    override fun serialize(
        value: RevisionAnchor,
        gen: com.fasterxml.jackson.core.JsonGenerator,
        provider: com.fasterxml.jackson.databind.SerializerProvider,
    ) {
        @Suppress("UNCHECKED_CAST")
        val mapper = (gen.codec as? com.fasterxml.jackson.databind.ObjectMapper) ?: com.fasterxml.jackson.databind.ObjectMapper().findAndRegisterModules()
        val node: com.fasterxml.jackson.databind.node.ObjectNode = when (value) {
            is RevisionAnchor.Paragraph -> {
                @Suppress("UNCHECKED_CAST")
                val n = mapper.valueToTree<com.fasterxml.jackson.databind.node.ObjectNode>(value as RevisionAnchor.Paragraph) as com.fasterxml.jackson.databind.node.ObjectNode
                n.put("type", "paragraph")
                n
            }
            is RevisionAnchor.TableCell -> {
                @Suppress("UNCHECKED_CAST")
                val n = mapper.valueToTree<com.fasterxml.jackson.databind.node.ObjectNode>(value as RevisionAnchor.TableCell) as com.fasterxml.jackson.databind.node.ObjectNode
                n.put("type", "table_cell")
                n
            }
            is RevisionAnchor.Page -> {
                @Suppress("UNCHECKED_CAST")
                val n = mapper.valueToTree<com.fasterxml.jackson.databind.node.ObjectNode>(value as RevisionAnchor.Page) as com.fasterxml.jackson.databind.node.ObjectNode
                n.put("type", "page")
                n
            }
            is RevisionAnchor.Slide -> {
                @Suppress("UNCHECKED_CAST")
                val n = mapper.valueToTree<com.fasterxml.jackson.databind.node.ObjectNode>(value as RevisionAnchor.Slide) as com.fasterxml.jackson.databind.node.ObjectNode
                n.put("type", "slide")
                n
            }
            is RevisionAnchor.Sheet -> {
                @Suppress("UNCHECKED_CAST")
                val n = mapper.valueToTree<com.fasterxml.jackson.databind.node.ObjectNode>(value as RevisionAnchor.Sheet) as com.fasterxml.jackson.databind.node.ObjectNode
                n.put("type", "sheet")
                n
            }
        }
        mapper.writeTree(gen, node)
    }
}
