// This file is auto-generated by alef — DO NOT EDIT.
// alef:hash:4e15143f4af1ae8bafbdb1506ef057da924484c66a19483966333558ad437e75
// To regenerate: alef generate
// To verify freshness: alef verify --exit-code
// Issues & docs: https://github.com/kreuzberg-dev/alef
package dev.kreuzberg;

import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import org.jspecify.annotations.Nullable;

/**
 * A single line in a unified-diff hunk.
 *
 * Defined here (rather than only in {@code crate.diff}) so {@code RevisionDelta} can
 * reference it unconditionally, without requiring the {@code diff} Cargo feature.
 * {@code crate.diff} re-exports this type verbatim.
 */
@com.fasterxml.jackson.annotation.JsonIgnoreProperties(ignoreUnknown = true)
@JsonDeserialize(using = DiffLineDeserializer.class)
@JsonSerialize(using = DiffLineSerializer.class)
public sealed interface DiffLine {

    /** Unchanged context line. */
    record Context(String value) implements DiffLine { }

    /** Line added in the "after" version. */
    record Added(String value) implements DiffLine { }

    /** Line removed from the "before" version. */
    record Removed(String value) implements DiffLine { }

    /** Returns the Context data if this is a Context variant, otherwise null. */
    default @Nullable String context() {
        return this instanceof Context e ? e.value() : null;
    }

    /** Returns the Added data if this is a Added variant, otherwise null. */
    default @Nullable String added() {
        return this instanceof Added e ? e.value() : null;
    }

    /** Returns the Removed data if this is a Removed variant, otherwise null. */
    default @Nullable String removed() {
        return this instanceof Removed e ? e.value() : null;
    }

}

// Custom deserializer for sealed interface with unwrapped variants
class DiffLineDeserializer extends StdDeserializer<DiffLine> {
    DiffLineDeserializer() {
        super(DiffLine.class);
    }

    @Override
    public DiffLine deserialize(JsonParser parser, DeserializationContext ctx)
            throws java.io.IOException {
        ObjectNode node = parser.getCodec().readTree(parser);
        com.fasterxml.jackson.databind.JsonNode tagNode = node.get("kind");
        if (tagNode == null || tagNode.isNull()) {
            throw new com.fasterxml.jackson.databind.JsonMappingException(
                parser, "Missing discriminator field: kind");
        }
        String tagValue = tagNode.asText();
        node.remove("kind");

        return switch (tagValue) {
            case "context" -> new DiffLine.Context(node.toString());
            case "added" -> new DiffLine.Added(node.toString());
            case "removed" -> new DiffLine.Removed(node.toString());
            default -> throw new com.fasterxml.jackson.databind.JsonMappingException(
                parser, "Unknown DiffLine discriminator: " + tagValue);
        };
    }
}

// Custom serializer for sealed interface with unwrapped variants — emits
// the discriminator tag alongside the inner record's fields (flat object).
class DiffLineSerializer extends StdSerializer<DiffLine> {
    private static final com.fasterxml.jackson.databind.ObjectMapper MAPPER =
        new com.fasterxml.jackson.databind.ObjectMapper()
            .registerModule(new com.fasterxml.jackson.datatype.jdk8.Jdk8Module())
            .setPropertyNamingStrategy(com.fasterxml.jackson.databind.PropertyNamingStrategies.SNAKE_CASE)
            .setSerializationInclusion(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL);

    DiffLineSerializer() {
        super(DiffLine.class);
    }

    @Override
    public void serialize(DiffLine value, JsonGenerator gen, SerializerProvider provider)
            throws java.io.IOException {
        String tag;
        Object inner;if (value instanceof DiffLine.Context v) {
            tag = "context";            inner = v.value();        }else if (value instanceof DiffLine.Added v) {
            tag = "added";            inner = v.value();        }else if (value instanceof DiffLine.Removed v) {
            tag = "removed";            inner = v.value();        }        else {
            throw new com.fasterxml.jackson.databind.JsonMappingException(gen,
                "Unknown DiffLine variant: " + value.getClass().getName());
        }

        gen.writeStartObject();
        gen.writeStringField("kind", tag);
        if (inner != null) {
            com.fasterxml.jackson.databind.JsonNode tree = MAPPER.valueToTree(inner);
            if (tree.isObject()) {
                java.util.Iterator<java.util.Map.Entry<String, com.fasterxml.jackson.databind.JsonNode>> it =
                    tree.fields();
                while (it.hasNext()) {
                    java.util.Map.Entry<String, com.fasterxml.jackson.databind.JsonNode> e = it.next();
                    gen.writeFieldName(e.getKey());
                    gen.writeTree(e.getValue());
                }
            }
        }
        gen.writeEndObject();
    }
}
