// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

import java.io.ByteArrayOutputStream;
import java.math.BigDecimal;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashSet;
import java.util.HexFormat;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.UUID;

import org.apache.parquet.variant.ImmutableMetadata;
import org.apache.parquet.variant.Variant;
import org.apache.parquet.variant.VariantArrayBuilder;
import org.apache.parquet.variant.VariantBuilder;
import org.apache.parquet.variant.VariantObjectBuilder;

/** Offline generator and verifier for the VariantEncoding v1 golden corpus. */
public final class ParquetVariantGolden {
    private static final String ARTIFACT = "org.apache.parquet:parquet-variant:1.17.0";
    private static final String JAR_SHA256 =
            "daecf8161e7bba63f7ba9fd62c1e8a77730c9a9d76a335191dc9d0a0fcaaec52";
    private static final HexFormat HEX = HexFormat.of();
    private static final Comparator<String> UNSIGNED_UTF8 =
            (left, right) -> Arrays.compareUnsigned(utf8(left), utf8(right));

    private ParquetVariantGolden() {}

    @FunctionalInterface
    private interface Appender {
        void append(VariantBuilder builder);
    }

    private record GoldenVector(
            String name,
            String provenance,
            String rootType,
            String expected,
            byte[] metadata,
            byte[] value) {}

    public static void main(String[] args) throws Exception {
        verifyArtifact();
        if (args.length == 2 && args[0].equals("generate")) {
            knownIncompatibilityCheck();
            Path output = Path.of(args[1]);
            Files.createDirectories(output);
            writeCorpus(
                    output.resolve("parquet_java_vectors.tsv"),
                    "java-to-doris",
                    javaToDorisVectors());
            writeCorpus(
                    output.resolve("doris_java_verified_vectors.tsv"),
                    "doris-to-java",
                    dorisToJavaVectors());
            return;
        }
        if (args.length == 1 && args[0].equals("extended")) {
            knownIncompatibilityCheck();
            verifyRealFourByteBoundaries();
            return;
        }
        throw new IllegalArgumentException(
                "Usage: ParquetVariantGolden generate <output-dir> | extended");
    }

    private static List<GoldenVector> javaToDorisVectors() {
        List<GoldenVector> vectors = new ArrayList<>();
        vectors.add(builderVector("primitive_null", "null", VariantBuilder::appendNull));
        vectors.add(builderVector("primitive_true", "bool:true", b -> b.appendBoolean(true)));
        vectors.add(builderVector("primitive_false", "bool:false", b -> b.appendBoolean(false)));
        vectors.add(builderVector("primitive_int8", "int8:-7", b -> b.appendByte((byte) -7)));
        vectors.add(builderVector("primitive_int16", "int16:128", b -> b.appendShort((short) 128)));
        vectors.add(builderVector("primitive_int32", "int32:32768", b -> b.appendInt(32768)));
        vectors.add(
                builderVector(
                        "primitive_int64", "int64:2147483648", b -> b.appendLong(2147483648L)));
        vectors.add(
                builderVector(
                        "primitive_int8_min", "int8:-128", b -> b.appendByte(Byte.MIN_VALUE)));
        vectors.add(
                builderVector(
                        "primitive_int8_max", "int8:127", b -> b.appendByte(Byte.MAX_VALUE)));
        vectors.add(
                builderVector(
                        "primitive_int16_min",
                        "int16:-32768",
                        b -> b.appendShort(Short.MIN_VALUE)));
        vectors.add(
                builderVector(
                        "primitive_int16_max",
                        "int16:32767",
                        b -> b.appendShort(Short.MAX_VALUE)));
        vectors.add(
                builderVector(
                        "primitive_int32_min",
                        "int32:-2147483648",
                        b -> b.appendInt(Integer.MIN_VALUE)));
        vectors.add(
                builderVector(
                        "primitive_int32_max",
                        "int32:2147483647",
                        b -> b.appendInt(Integer.MAX_VALUE)));
        vectors.add(
                builderVector(
                        "primitive_int64_min",
                        "int64:-9223372036854775808",
                        b -> b.appendLong(Long.MIN_VALUE)));
        vectors.add(
                builderVector(
                        "primitive_int64_max",
                        "int64:9223372036854775807",
                        b -> b.appendLong(Long.MAX_VALUE)));
        vectors.add(
                builderVector(
                        "primitive_double",
                        "double:400921fb54442d18",
                        b -> b.appendDouble(Math.PI)));
        vectors.add(
                builderVector(
                        "primitive_decimal4",
                        "decimal4:1234567:2",
                        b -> b.appendDecimal(new BigDecimal("12345.67"))));
        vectors.add(
                builderVector(
                        "primitive_decimal8",
                        "decimal8:123456789012345:5",
                        b -> b.appendDecimal(new BigDecimal("1234567890.12345"))));
        vectors.add(
                builderVector(
                        "primitive_decimal16",
                        "decimal16:12345678901234567891234567890:10",
                        b -> b.appendDecimal(new BigDecimal("1234567890123456789.1234567890"))));
        vectors.add(
                builderVector(
                        "primitive_decimal4_precision9_max",
                        "decimal4:999999999:2",
                        b -> b.appendDecimal(new BigDecimal("9999999.99"))));
        vectors.add(
                builderVector(
                        "primitive_decimal4_precision9_min",
                        "decimal4:-999999999:2",
                        b -> b.appendDecimal(new BigDecimal("-9999999.99"))));
        vectors.add(
                builderVector(
                        "primitive_decimal8_precision10_min",
                        "decimal8:1000000000:0",
                        b -> b.appendDecimal(new BigDecimal("1000000000"))));
        vectors.add(
                builderVector(
                        "primitive_decimal8_precision18_max",
                        "decimal8:999999999999999999:0",
                        b -> b.appendDecimal(new BigDecimal("999999999999999999"))));
        vectors.add(
                builderVector(
                        "primitive_decimal16_precision19_min",
                        "decimal16:1000000000000000000:0",
                        b -> b.appendDecimal(new BigDecimal("1000000000000000000"))));
        vectors.add(
                builderVector(
                        "primitive_decimal16_precision38_max",
                        "decimal16:99999999999999999999999999999999999999:0",
                        b ->
                                b.appendDecimal(
                                        new BigDecimal(
                                                "99999999999999999999999999999999999999"))));
        vectors.add(
                builderVector(
                        "primitive_decimal4_scale38_min_unit",
                        "decimal4:-1:38",
                        b ->
                                b.appendDecimal(
                                        new BigDecimal(
                                                "-0.00000000000000000000000000000000000001"))));
        vectors.add(
                builderVector(
                        "primitive_decimal4_trailing_zero",
                        "decimal4:12300:4",
                        b -> b.appendDecimal(new BigDecimal("1.2300"))));
        vectors.add(builderVector("primitive_date", "date:-12345", b -> b.appendDate(-12345)));
        vectors.add(
                builderVector(
                        "primitive_timestamp_tz",
                        "timestamp_tz:-1234567890123",
                        b -> b.appendTimestampTz(-1234567890123L)));
        vectors.add(
                builderVector(
                        "primitive_timestamp_ntz",
                        "timestamp_ntz:2234567890123",
                        b -> b.appendTimestampNtz(2234567890123L)));
        vectors.add(
                builderVector(
                        "primitive_float", "float:3fc00000", b -> b.appendFloat(1.5F)));
        vectors.add(
                builderVector(
                        "primitive_binary",
                        "binary:0001ff",
                        b -> b.appendBinary(ByteBuffer.wrap(new byte[] {0, 1, (byte) 0xFF}))));
        String longString = "L".repeat(64);
        vectors.add(
                builderVector(
                        "primitive_long_string",
                        "string:" + hexUtf8(longString),
                        b -> b.appendString(longString)));
        vectors.add(
                builderVector(
                        "primitive_time",
                        "time:86399999999",
                        b -> b.appendTime(86_399_999_999L)));
        vectors.add(
                builderVector(
                        "primitive_timestamp_nanos_tz",
                        "timestamp_nanos_tz:-3234567890123",
                        b -> b.appendTimestampNanosTz(-3234567890123L)));
        vectors.add(
                builderVector(
                        "primitive_timestamp_nanos_ntz",
                        "timestamp_nanos_ntz:4234567890123",
                        b -> b.appendTimestampNanosNtz(4234567890123L)));
        UUID uuid = UUID.fromString("00112233-4455-6677-8899-aabbccddeeff");
        vectors.add(
                builderVector(
                        "primitive_uuid", "uuid:" + uuid, b -> b.appendUUID(uuid)));

        vectors.add(builderVector("short_string_empty", "string:", b -> b.appendString("")));
        String short63 = "s".repeat(63);
        vectors.add(
                builderVector(
                        "short_string_63",
                        "string:" + hexUtf8(short63),
                        b -> b.appendString(short63)));
        String unicode = "A\u00E9\u4E2D\uD800\uDC00";
        vectors.add(
                builderVector(
                        "short_string_unicode",
                        "string:" + hexUtf8(unicode),
                        b -> b.appendString(unicode)));

        vectors.add(
                builderVector(
                        "empty_object",
                        "object{}",
                        builder -> {
                            builder.startObject();
                            builder.endObject();
                        }));
        vectors.add(
                builderVector(
                        "empty_array",
                        "array[]",
                        builder -> {
                            builder.startArray();
                            builder.endArray();
                        }));
        vectors.add(normalObjectVector());
        vectors.add(normalArrayVector());
        vectors.add(normalNestedVector());
        vectors.add(unicodeBmpObjectVector());
        vectors.add(unicodeSupplementaryObjectVector());

        vectors.add(metadataBoundaryVector(255));
        vectors.add(metadataBoundaryVector(256));
        vectors.add(metadataBoundaryVector(65_535));
        vectors.add(metadataBoundaryVector(65_536));
        vectors.add(offsetBoundaryVector(255));
        vectors.add(offsetBoundaryVector(256));
        vectors.add(offsetBoundaryVector(65_535));
        vectors.add(offsetBoundaryVector(65_536));
        vectors.add(arrayCountBoundaryVector(255));
        vectors.add(arrayCountBoundaryVector(256));
        vectors.add(objectIdBoundaryVector(256));
        vectors.add(objectIdBoundaryVector(257));

        vectors.add(rawMetadataWidthFourVector());
        vectors.add(rawArrayOffsetWidthFourVector());
        vectors.add(rawObjectIdWidthVector(3));
        vectors.add(rawObjectIdWidthVector(4));
        vectors.add(rawNonMonotonicObjectVector());
        return vectors;
    }

    private static List<GoldenVector> dorisToJavaVectors() {
        List<GoldenVector> vectors = new ArrayList<>();
        vectors.add(canonicalVector("doris_null", "null", List.of(), VariantBuilder::appendNull));
        vectors.add(
                canonicalVector(
                        "doris_true", "bool:true", List.of(), b -> b.appendBoolean(true)));
        vectors.add(
                canonicalVector(
                        "doris_false", "bool:false", List.of(), b -> b.appendBoolean(false)));
        vectors.add(
                canonicalVector(
                        "doris_int8", "int8:-7", List.of(), b -> b.appendByte((byte) -7)));
        vectors.add(
                canonicalVector(
                        "doris_int16", "int16:128", List.of(), b -> b.appendShort((short) 128)));
        vectors.add(
                canonicalVector(
                        "doris_int32", "int32:32768", List.of(), b -> b.appendInt(32768)));
        vectors.add(
                canonicalVector(
                        "doris_int64",
                        "int64:2147483648",
                        List.of(),
                        b -> b.appendLong(2147483648L)));
        vectors.add(
                canonicalVector(
                        "doris_int8_min",
                        "int8:-128",
                        List.of(),
                        b -> b.appendByte(Byte.MIN_VALUE)));
        vectors.add(
                canonicalVector(
                        "doris_int8_max",
                        "int8:127",
                        List.of(),
                        b -> b.appendByte(Byte.MAX_VALUE)));
        vectors.add(
                canonicalVector(
                        "doris_int16_min",
                        "int16:-32768",
                        List.of(),
                        b -> b.appendShort(Short.MIN_VALUE)));
        vectors.add(
                canonicalVector(
                        "doris_int16_max",
                        "int16:32767",
                        List.of(),
                        b -> b.appendShort(Short.MAX_VALUE)));
        vectors.add(
                canonicalVector(
                        "doris_int32_min",
                        "int32:-2147483648",
                        List.of(),
                        b -> b.appendInt(Integer.MIN_VALUE)));
        vectors.add(
                canonicalVector(
                        "doris_int32_max",
                        "int32:2147483647",
                        List.of(),
                        b -> b.appendInt(Integer.MAX_VALUE)));
        vectors.add(
                canonicalVector(
                        "doris_int64_min",
                        "int64:-9223372036854775808",
                        List.of(),
                        b -> b.appendLong(Long.MIN_VALUE)));
        vectors.add(
                canonicalVector(
                        "doris_int64_max",
                        "int64:9223372036854775807",
                        List.of(),
                        b -> b.appendLong(Long.MAX_VALUE)));
        vectors.add(
                canonicalVector(
                        "doris_double",
                        "double:400921fb54442d18",
                        List.of(),
                        b -> b.appendDouble(Math.PI)));
        vectors.add(
                canonicalVector(
                        "doris_decimal4",
                        "decimal4:1234567:2",
                        List.of(),
                        b -> b.appendDecimal(new BigDecimal("12345.67"))));
        vectors.add(
                canonicalVector(
                        "doris_decimal8",
                        "decimal8:123456789012345:5",
                        List.of(),
                        b -> b.appendDecimal(new BigDecimal("1234567890.12345"))));
        vectors.add(
                canonicalVector(
                        "doris_decimal16",
                        "decimal16:12345678901234567891234567890:10",
                        List.of(),
                        b -> b.appendDecimal(new BigDecimal("1234567890123456789.1234567890"))));
        vectors.add(
                canonicalVector(
                        "doris_decimal4_precision9_max",
                        "decimal4:999999999:2",
                        List.of(),
                        b -> b.appendDecimal(new BigDecimal("9999999.99"))));
        vectors.add(
                canonicalVector(
                        "doris_decimal4_precision9_min",
                        "decimal4:-999999999:2",
                        List.of(),
                        b -> b.appendDecimal(new BigDecimal("-9999999.99"))));
        vectors.add(
                canonicalVector(
                        "doris_decimal8_precision10_min",
                        "decimal8:1000000000:0",
                        List.of(),
                        b -> b.appendDecimal(new BigDecimal("1000000000"))));
        vectors.add(
                canonicalVector(
                        "doris_decimal8_precision18_max",
                        "decimal8:999999999999999999:0",
                        List.of(),
                        b -> b.appendDecimal(new BigDecimal("999999999999999999"))));
        vectors.add(
                canonicalVector(
                        "doris_decimal16_precision19_min",
                        "decimal16:1000000000000000000:0",
                        List.of(),
                        b -> b.appendDecimal(new BigDecimal("1000000000000000000"))));
        vectors.add(
                canonicalVector(
                        "doris_decimal16_precision38_max",
                        "decimal16:99999999999999999999999999999999999999:0",
                        List.of(),
                        b ->
                                b.appendDecimal(
                                        new BigDecimal(
                                                "99999999999999999999999999999999999999"))));
        vectors.add(
                canonicalVector(
                        "doris_decimal4_scale38_min_unit",
                        "decimal4:-1:38",
                        List.of(),
                        b ->
                                b.appendDecimal(
                                        new BigDecimal(
                                                "-0.00000000000000000000000000000000000001"))));
        vectors.add(
                canonicalVector(
                        "doris_decimal4_trailing_zero",
                        "decimal4:12300:4",
                        List.of(),
                        b -> b.appendDecimal(new BigDecimal("1.2300"))));
        vectors.add(
                canonicalVector(
                        "doris_date", "date:-12345", List.of(), b -> b.appendDate(-12345)));
        vectors.add(
                canonicalVector(
                        "doris_timestamp_tz",
                        "timestamp_tz:-1234567890123",
                        List.of(),
                        b -> b.appendTimestampTz(-1234567890123L)));
        vectors.add(
                canonicalVector(
                        "doris_timestamp_ntz",
                        "timestamp_ntz:2234567890123",
                        List.of(),
                        b -> b.appendTimestampNtz(2234567890123L)));
        vectors.add(
                canonicalVector(
                        "doris_float",
                        "float:3fc00000",
                        List.of(),
                        b -> b.appendFloat(1.5F)));
        vectors.add(
                canonicalVector(
                        "doris_binary",
                        "binary:0001ff",
                        List.of(),
                        b -> b.appendBinary(ByteBuffer.wrap(new byte[] {0, 1, (byte) 0xFF}))));
        String longString = "L".repeat(64);
        vectors.add(
                canonicalVector(
                        "doris_long_string",
                        "string:" + hexUtf8(longString),
                        List.of(),
                        b -> b.appendString(longString)));
        vectors.add(
                canonicalVector(
                        "doris_time",
                        "time:86399999999",
                        List.of(),
                        b -> b.appendTime(86_399_999_999L)));
        vectors.add(
                canonicalVector(
                        "doris_timestamp_nanos_tz",
                        "timestamp_nanos_tz:-3234567890123",
                        List.of(),
                        b -> b.appendTimestampNanosTz(-3234567890123L)));
        vectors.add(
                canonicalVector(
                        "doris_timestamp_nanos_ntz",
                        "timestamp_nanos_ntz:4234567890123",
                        List.of(),
                        b -> b.appendTimestampNanosNtz(4234567890123L)));
        UUID uuid = UUID.fromString("00112233-4455-6677-8899-aabbccddeeff");
        vectors.add(
                canonicalVector(
                        "doris_uuid", "uuid:" + uuid, List.of(), b -> b.appendUUID(uuid)));
        vectors.add(
                canonicalVector(
                        "doris_short_empty", "string:", List.of(), b -> b.appendString("")));
        String short63 = "s".repeat(63);
        vectors.add(
                canonicalVector(
                        "doris_short_63",
                        "string:" + hexUtf8(short63),
                        List.of(),
                        b -> b.appendString(short63)));
        String unicode = "A\u00E9\u4E2D\uD800\uDC00";
        vectors.add(
                canonicalVector(
                        "doris_unicode_string",
                        "string:" + hexUtf8(unicode),
                        List.of(),
                        b -> b.appendString(unicode)));
        vectors.add(canonicalObjectVector());
        vectors.add(canonicalArrayVector());
        vectors.add(canonicalNestedVector());
        vectors.add(canonicalUnicodeObjectVector());
        return vectors;
    }

    private static GoldenVector builderVector(String name, String expected, Appender append) {
        VariantBuilder builder = new VariantBuilder();
        append.append(builder);
        GoldenVector vector =
                checkedVector(name, "parquet-java-builder", expected, builder.build());
        if ((vector.metadata()[0] & 0x10) != 0) {
            throw new IllegalStateException("MetadataBuilder unexpectedly set sorted_strings");
        }
        return vector;
    }

    private static void verifyArtifact() throws Exception {
        Path artifact =
                Path.of(
                        Variant.class
                                .getProtectionDomain()
                                .getCodeSource()
                                .getLocation()
                                .toURI());
        if (!Files.isRegularFile(artifact)) {
            throw new IllegalStateException(
                    "parquet-java Variant classes were not loaded from a jar: " + artifact);
        }
        byte[] digest =
                MessageDigest.getInstance("SHA-256").digest(Files.readAllBytes(artifact));
        String actual = HEX.formatHex(digest);
        if (!actual.equals(JAR_SHA256)) {
            throw new IllegalStateException(
                    "parquet-java jar SHA-256 mismatch: expected "
                            + JAR_SHA256
                            + ", got "
                            + actual
                            + " from "
                            + artifact);
        }
    }

    private static GoldenVector canonicalVector(
            String name, String expected, List<String> keys, Appender append) {
        List<String> sortedKeys = new ArrayList<>(keys);
        sortedKeys.sort(UNSIGNED_UTF8);
        if (new HashSet<>(sortedKeys).size() != sortedKeys.size()) {
            throw new IllegalArgumentException("Duplicate canonical metadata key for " + name);
        }
        byte[] encodedMetadata = encodeMetadata(sortedKeys, true, 0);
        ImmutableMetadata metadata = new ImmutableMetadata(ByteBuffer.wrap(encodedMetadata));
        for (int index = 0; index < sortedKeys.size(); ++index) {
            if (metadata.getOrInsert(sortedKeys.get(index)) != index) {
                throw new IllegalStateException("Immutable metadata id mismatch for " + name);
            }
        }
        VariantBuilder builder = new VariantBuilder(metadata);
        append.append(builder);
        Variant variant = builder.build();
        if (!Arrays.equals(encodedMetadata, bytes(variant.getMetadataBuffer()))) {
            throw new IllegalStateException("Canonical metadata changed for " + name);
        }
        return checkedVector(name, "doris-block-builder-java-validated", expected, variant);
    }

    private static GoldenVector checkedVector(
            String name, String provenance, String expected, Variant variant) {
        String actual = describe(variant);
        if (!actual.equals(expected)) {
            throw new IllegalStateException(
                    "Typed accessor mismatch for " + name + ": expected " + expected + ", got " + actual);
        }
        return new GoldenVector(
                name,
                provenance,
                rootType(variant),
                expected,
                bytes(variant.getMetadataBuffer()),
                bytes(variant.getValueBuffer()));
    }

    private static GoldenVector checkedRawVector(
            String name, String expected, byte[] metadata, byte[] value) {
        ImmutableMetadata parsed = new ImmutableMetadata(ByteBuffer.wrap(metadata));
        if (!Arrays.equals(metadata, bytes(parsed.getEncodedBuffer()))) {
            throw new IllegalStateException("ImmutableMetadata changed raw bytes for " + name);
        }
        return checkedVector(
                name,
                "spec-raw-java-validated",
                expected,
                new Variant(value, metadata));
    }

    private static GoldenVector normalObjectVector() {
        String expected = "object{61=string:78;7a=int32:1}";
        return builderVector(
                "object_unsorted_metadata",
                expected,
                builder -> {
                    VariantObjectBuilder object = builder.startObject();
                    object.appendKey("z");
                    object.appendInt(1);
                    object.appendKey("a");
                    object.appendString("x");
                    builder.endObject();
                });
    }

    private static GoldenVector normalArrayVector() {
        return builderVector(
                "array_ordered",
                "array[int8:1;string:78;bool:false]",
                builder -> {
                    VariantArrayBuilder array = builder.startArray();
                    array.appendByte((byte) 1);
                    array.appendString("x");
                    array.appendBoolean(false);
                    builder.endArray();
                });
    }

    private static GoldenVector normalNestedVector() {
        String expected = "object{617272=array[int8:7;object{696e73696465=bool:false}]}";
        return builderVector(
                "nested_object_array",
                expected,
                builder -> {
                    VariantObjectBuilder root = builder.startObject();
                    root.appendKey("arr");
                    VariantArrayBuilder array = root.startArray();
                    array.appendByte((byte) 7);
                    VariantObjectBuilder inner = array.startObject();
                    inner.appendKey("inside");
                    inner.appendBoolean(false);
                    array.endObject();
                    root.endArray();
                    builder.endObject();
                });
    }

    private static GoldenVector unicodeBmpObjectVector() {
        String first = "\u00E9";
        String second = "\uE000";
        String expected =
                "object{" + hexUtf8(first) + "=int32:1;" + hexUtf8(second) + "=int32:2}";
        return builderVector(
                "unicode_bmp_order",
                expected,
                builder -> {
                    VariantObjectBuilder object = builder.startObject();
                    object.appendKey(second);
                    object.appendInt(2);
                    object.appendKey(first);
                    object.appendInt(1);
                    builder.endObject();
                });
    }

    private static GoldenVector unicodeSupplementaryObjectVector() {
        String first = "\uD800\uDC00";
        String second = "\uD800\uDC01";
        String expected =
                "object{" + hexUtf8(first) + "=int32:1;" + hexUtf8(second) + "=int32:2}";
        return builderVector(
                "unicode_supplementary_order",
                expected,
                builder -> {
                    VariantObjectBuilder object = builder.startObject();
                    object.appendKey(second);
                    object.appendInt(2);
                    object.appendKey(first);
                    object.appendInt(1);
                    builder.endObject();
                });
    }

    private static GoldenVector metadataBoundaryVector(int keyBytes) {
        String key = "k".repeat(keyBytes);
        GoldenVector vector =
                builderVector(
                "metadata_bytes_" + keyBytes,
                "object{" + hexUtf8(key) + "=null}",
                builder -> {
                    VariantObjectBuilder object = builder.startObject();
                    object.appendKey(key);
                    object.appendNull();
                    builder.endObject();
                });
        int expectedWidth = minUnsignedWidth(keyBytes);
        int actualWidth = ((vector.metadata()[0] >>> 6) & 0x03) + 1;
        if (actualWidth != expectedWidth) {
            throw new IllegalStateException("Metadata width boundary mismatch at " + keyBytes);
        }
        return vector;
    }

    private static GoldenVector offsetBoundaryVector(int encodedChildBytes) {
        byte[] payload = new byte[encodedChildBytes - 5];
        Arrays.fill(payload, (byte) 0xAB);
        GoldenVector vector =
                builderVector(
                "array_offset_bytes_" + encodedChildBytes,
                "array[binary:" + HEX.formatHex(payload) + "]",
                builder -> {
                    VariantArrayBuilder array = builder.startArray();
                    array.appendBinary(ByteBuffer.wrap(payload));
                    builder.endArray();
                });
        int valueHeader = (vector.value()[0] & 0xFF) >>> 2;
        int actualWidth = (valueHeader & 0x03) + 1;
        if (actualWidth != minUnsignedWidth(encodedChildBytes)) {
            throw new IllegalStateException(
                    "Array offset width boundary mismatch at " + encodedChildBytes);
        }
        return vector;
    }

    private static GoldenVector arrayCountBoundaryVector(int count) {
        GoldenVector vector =
                builderVector(
                "array_count_" + count,
                repeatedArrayExpected(count),
                builder -> {
                    VariantArrayBuilder array = builder.startArray();
                    for (int index = 0; index < count; ++index) {
                        array.appendNull();
                    }
                    builder.endArray();
                });
        int valueHeader = (vector.value()[0] & 0xFF) >>> 2;
        boolean isLarge = (valueHeader & 0x04) != 0;
        if (isLarge != (count > 255)) {
            throw new IllegalStateException("Array count boundary mismatch at " + count);
        }
        return vector;
    }

    private static GoldenVector objectIdBoundaryVector(int count) {
        List<String> keys = numberedKeys(count);
        GoldenVector vector =
                builderVector(
                "object_id_count_" + count,
                nullObjectExpected(keys),
                builder -> {
                    VariantObjectBuilder object = builder.startObject();
                    for (String key : keys) {
                        object.appendKey(key);
                        object.appendNull();
                    }
                    builder.endObject();
                });
        int valueHeader = (vector.value()[0] & 0xFF) >>> 2;
        int idWidth = ((valueHeader >>> 2) & 0x03) + 1;
        boolean isLarge = (valueHeader & 0x10) != 0;
        if (idWidth != minUnsignedWidth(count - 1) || isLarge != (count > 255)) {
            throw new IllegalStateException("Object id/count boundary mismatch at " + count);
        }
        return vector;
    }

    private static GoldenVector rawMetadataWidthFourVector() {
        byte[] metadata = encodeMetadata(List.of(), true, 4);
        return checkedRawVector(
                "raw_metadata_width_4", "null", metadata, new byte[] {0});
    }

    private static GoldenVector rawArrayOffsetWidthFourVector() {
        byte[] metadata = encodeMetadata(List.of(), true, 1);
        byte[] value = rawArray(4, List.of(new byte[] {0}));
        return checkedRawVector("raw_array_offset_width_4", "array[null]", metadata, value);
    }

    private static GoldenVector rawObjectIdWidthVector(int idWidth) {
        byte[] metadata = encodeMetadata(List.of("a"), true, 1);
        byte[] value = rawObject(idWidth, 1, new int[] {0}, new int[] {0, 1}, new byte[] {0});
        return checkedRawVector(
                "raw_object_id_width_" + idWidth, "object{61=null}", metadata, value);
    }

    private static GoldenVector rawNonMonotonicObjectVector() {
        byte[] metadata = encodeMetadata(List.of("a", "b"), true, 1);
        byte[] shortX = shortString("x");
        byte[] intOne = new byte[] {(byte) (3 << 2), 1};
        byte[] values = concat(shortX, intOne);
        byte[] value = rawObject(1, 1, new int[] {0, 1}, new int[] {2, 0, 4}, values);
        return checkedRawVector(
                "raw_object_nonmonotonic_offsets",
                "object{61=int8:1;62=string:78}",
                metadata,
                value);
    }

    private static GoldenVector canonicalObjectVector() {
        return canonicalVector(
                "doris_object",
                "object{61=string:78;7a=int8:1}",
                List.of("z", "a"),
                builder -> {
                    VariantObjectBuilder object = builder.startObject();
                    object.appendKey("z");
                    object.appendByte((byte) 1);
                    object.appendKey("a");
                    object.appendString("x");
                    builder.endObject();
                });
    }

    private static GoldenVector canonicalArrayVector() {
        return canonicalVector(
                "doris_array",
                "array[int8:1;string:78;bool:false]",
                List.of(),
                builder -> {
                    VariantArrayBuilder array = builder.startArray();
                    array.appendByte((byte) 1);
                    array.appendString("x");
                    array.appendBoolean(false);
                    builder.endArray();
                });
    }

    private static GoldenVector canonicalNestedVector() {
        return canonicalVector(
                "doris_nested",
                "object{617272=array[int8:7;object{696e73696465=bool:false}]}",
                List.of("arr", "inside"),
                builder -> {
                    VariantObjectBuilder root = builder.startObject();
                    root.appendKey("arr");
                    VariantArrayBuilder array = root.startArray();
                    array.appendByte((byte) 7);
                    VariantObjectBuilder inner = array.startObject();
                    inner.appendKey("inside");
                    inner.appendBoolean(false);
                    array.endObject();
                    root.endArray();
                    builder.endObject();
                });
    }

    private static GoldenVector canonicalUnicodeObjectVector() {
        String first = "\u00E9";
        String second = "\uE000";
        return canonicalVector(
                "doris_unicode_object",
                "object{" + hexUtf8(first) + "=int8:1;" + hexUtf8(second) + "=int8:2}",
                List.of(second, first),
                builder -> {
                    VariantObjectBuilder object = builder.startObject();
                    object.appendKey(second);
                    object.appendByte((byte) 2);
                    object.appendKey(first);
                    object.appendByte((byte) 1);
                    builder.endObject();
                });
    }

    private static String describe(Variant variant) {
        return switch (variant.getType()) {
            case NULL -> "null";
            case BOOLEAN -> "bool:" + variant.getBoolean();
            case BYTE -> "int8:" + variant.getByte();
            case SHORT -> "int16:" + variant.getShort();
            case INT -> "int32:" + variant.getInt();
            case LONG -> "int64:" + variant.getLong();
            case DOUBLE ->
                    "double:"
                            + String.format(
                                    Locale.ROOT,
                                    "%016x",
                                    Double.doubleToRawLongBits(variant.getDouble()));
            case DECIMAL4 -> decimalDescription("decimal4", variant.getDecimal());
            case DECIMAL8 -> decimalDescription("decimal8", variant.getDecimal());
            case DECIMAL16 -> decimalDescription("decimal16", variant.getDecimal());
            case DATE -> "date:" + variant.getInt();
            case TIMESTAMP_TZ -> "timestamp_tz:" + variant.getLong();
            case TIMESTAMP_NTZ -> "timestamp_ntz:" + variant.getLong();
            case FLOAT ->
                    "float:"
                            + String.format(
                                    Locale.ROOT,
                                    "%08x",
                                    Float.floatToRawIntBits(variant.getFloat()));
            case BINARY -> "binary:" + HEX.formatHex(bytes(variant.getBinary()));
            case STRING -> "string:" + hexUtf8(variant.getString());
            case TIME -> "time:" + variant.getLong();
            case TIMESTAMP_NANOS_TZ -> "timestamp_nanos_tz:" + variant.getLong();
            case TIMESTAMP_NANOS_NTZ -> "timestamp_nanos_ntz:" + variant.getLong();
            case UUID -> "uuid:" + variant.getUUID().toString().toLowerCase(Locale.ROOT);
            case OBJECT -> describeObject(variant);
            case ARRAY -> describeArray(variant);
        };
    }

    private static String decimalDescription(String type, BigDecimal decimal) {
        return type + ":" + decimal.unscaledValue() + ":" + decimal.scale();
    }

    private static String describeObject(Variant variant) {
        StringBuilder result = new StringBuilder("object{");
        for (int index = 0; index < variant.numObjectElements(); ++index) {
            if (index != 0) {
                result.append(';');
            }
            Variant.ObjectField field = variant.getFieldAtIndex(index);
            Variant byKey = variant.getFieldByKey(field.key);
            if (byKey == null || !describe(byKey).equals(describe(field.value))) {
                throw new IllegalStateException("Official object lookup disagrees with iteration");
            }
            result.append(hexUtf8(field.key)).append('=').append(describe(field.value));
        }
        return result.append('}').toString();
    }

    private static String describeArray(Variant variant) {
        StringBuilder result = new StringBuilder("array[");
        for (int index = 0; index < variant.numArrayElements(); ++index) {
            if (index != 0) {
                result.append(';');
            }
            result.append(describe(variant.getElementAtIndex(index)));
        }
        return result.append(']').toString();
    }

    private static String rootType(Variant variant) {
        return switch (variant.getType()) {
            case NULL -> "null";
            case BOOLEAN -> "boolean";
            case BYTE -> "byte";
            case SHORT -> "short";
            case INT -> "int";
            case LONG -> "long";
            case STRING -> "string";
            case DOUBLE -> "double";
            case DECIMAL4 -> "decimal4";
            case DECIMAL8 -> "decimal8";
            case DECIMAL16 -> "decimal16";
            case DATE -> "date";
            case TIMESTAMP_TZ -> "timestamp_tz";
            case TIMESTAMP_NTZ -> "timestamp_ntz";
            case FLOAT -> "float";
            case BINARY -> "binary";
            case TIME -> "time";
            case TIMESTAMP_NANOS_TZ -> "timestamp_nanos_tz";
            case TIMESTAMP_NANOS_NTZ -> "timestamp_nanos_ntz";
            case UUID -> "uuid";
            case OBJECT -> "object";
            case ARRAY -> "array";
        };
    }

    private static void writeCorpus(Path file, String corpus, List<GoldenVector> vectors)
            throws Exception {
        vectors.sort(Comparator.comparing(GoldenVector::name));
        Set<String> names = new HashSet<>();
        StringBuilder output = new StringBuilder();
        output.append("# Licensed to the Apache Software Foundation (ASF) under one\n");
        output.append("# or more contributor license agreements.  See the NOTICE file\n");
        output.append("# distributed with this work for additional information\n");
        output.append("# regarding copyright ownership.  The ASF licenses this file\n");
        output.append("# to you under the Apache License, Version 2.0 (the\n");
        output.append("# \"License\"); you may not use this file except in compliance\n");
        output.append("# with the License.  You may obtain a copy of the License at\n");
        output.append("#\n");
        output.append("#   http://www.apache.org/licenses/LICENSE-2.0\n");
        output.append("#\n");
        output.append("# Unless required by applicable law or agreed to in writing,\n");
        output.append("# software distributed under the License is distributed on an\n");
        output.append("# \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n");
        output.append("# KIND, either express or implied.  See the License for the\n");
        output.append("# specific language governing permissions and limitations\n");
        output.append("# under the License.\n");
        output.append("#\n");
        output.append("# variant-golden-v1\n");
        output.append("# artifact=").append(ARTIFACT).append('\n');
        output.append("# jar_sha256=").append(JAR_SHA256).append('\n');
        output.append("# corpus=").append(corpus).append('\n');
        output.append("# columns=name\\tprovenance\\troot_type\\texpected\\tmetadata_hex\\tvalue_hex\n");
        for (GoldenVector vector : vectors) {
            if (!names.add(vector.name())) {
                throw new IllegalStateException("Duplicate vector name " + vector.name());
            }
            output.append(vector.name())
                    .append('\t')
                    .append(vector.provenance())
                    .append('\t')
                    .append(vector.rootType())
                    .append('\t')
                    .append(vector.expected())
                    .append('\t')
                    .append(HEX.formatHex(vector.metadata()))
                    .append('\t')
                    .append(HEX.formatHex(vector.value()))
                    .append('\n');
        }
        Files.writeString(file, output, StandardCharsets.UTF_8);
    }

    private static byte[] encodeMetadata(List<String> keys, boolean sorted, int forcedWidth) {
        List<byte[]> encodedKeys = keys.stream().map(ParquetVariantGolden::utf8).toList();
        long stringsSize = encodedKeys.stream().mapToLong(bytes -> bytes.length).sum();
        int width =
                forcedWidth == 0
                        ? minUnsignedWidth(Math.max(keys.size(), stringsSize))
                        : forcedWidth;
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        output.write(1 | (sorted ? 0x10 : 0) | ((width - 1) << 6));
        writeUnsigned(output, keys.size(), width);
        long offset = 0;
        writeUnsigned(output, offset, width);
        for (byte[] key : encodedKeys) {
            offset += key.length;
            writeUnsigned(output, offset, width);
        }
        for (byte[] key : encodedKeys) {
            output.writeBytes(key);
        }
        return output.toByteArray();
    }

    private static byte[] rawArray(int offsetWidth, List<byte[]> children) {
        ByteArrayOutputStream values = new ByteArrayOutputStream();
        int[] offsets = new int[children.size() + 1];
        for (int index = 0; index < children.size(); ++index) {
            offsets[index] = values.size();
            values.writeBytes(children.get(index));
        }
        offsets[children.size()] = values.size();
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        output.write(3 | ((offsetWidth - 1) << 2));
        output.write(children.size());
        for (int offset : offsets) {
            writeUnsigned(output, offset, offsetWidth);
        }
        output.writeBytes(values.toByteArray());
        return output.toByteArray();
    }

    private static byte[] rawObject(
            int idWidth,
            int offsetWidth,
            int[] ids,
            int[] offsets,
            byte[] values) {
        if (offsets.length != ids.length + 1 || ids.length > 255) {
            throw new IllegalArgumentException("Invalid compact raw object shape");
        }
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        output.write(2 | ((offsetWidth - 1) << 2) | ((idWidth - 1) << 4));
        output.write(ids.length);
        for (int id : ids) {
            writeUnsigned(output, id, idWidth);
        }
        for (int offset : offsets) {
            writeUnsigned(output, offset, offsetWidth);
        }
        output.writeBytes(values);
        return output.toByteArray();
    }

    private static byte[] shortString(String value) {
        byte[] encoded = utf8(value);
        if (encoded.length > 63) {
            throw new IllegalArgumentException("Not a short string");
        }
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        output.write((encoded.length << 2) | 1);
        output.writeBytes(encoded);
        return output.toByteArray();
    }

    private static void writeUnsigned(ByteArrayOutputStream output, long value, int width) {
        for (int index = 0; index < width; ++index) {
            output.write((int) (value >>> (index * 8)) & 0xFF);
        }
    }

    private static int minUnsignedWidth(long value) {
        if (value <= 0xFFL) {
            return 1;
        }
        if (value <= 0xFFFFL) {
            return 2;
        }
        if (value <= 0xFFFFFFL) {
            return 3;
        }
        return 4;
    }

    private static List<String> numberedKeys(int count) {
        List<String> keys = new ArrayList<>();
        for (int index = 0; index < count; ++index) {
            keys.add(String.format(Locale.ROOT, "k%03d", index));
        }
        return keys;
    }

    private static String nullObjectExpected(List<String> keys) {
        StringBuilder result = new StringBuilder("object{");
        for (int index = 0; index < keys.size(); ++index) {
            if (index != 0) {
                result.append(';');
            }
            result.append(hexUtf8(keys.get(index))).append("=null");
        }
        return result.append('}').toString();
    }

    private static String repeatedArrayExpected(int count) {
        StringBuilder result = new StringBuilder("array[");
        for (int index = 0; index < count; ++index) {
            if (index != 0) {
                result.append(';');
            }
            result.append("null");
        }
        return result.append(']').toString();
    }

    private static byte[] concat(byte[] left, byte[] right) {
        byte[] result = Arrays.copyOf(left, left.length + right.length);
        System.arraycopy(right, 0, result, left.length, right.length);
        return result;
    }

    private static byte[] bytes(ByteBuffer buffer) {
        ByteBuffer copy = buffer.duplicate();
        byte[] result = new byte[copy.remaining()];
        copy.get(result);
        return result;
    }

    private static byte[] utf8(String value) {
        return value.getBytes(StandardCharsets.UTF_8);
    }

    private static String hexUtf8(String value) {
        return HEX.formatHex(utf8(value));
    }

    private static void knownIncompatibilityCheck() {
        String bmp = "\uE000";
        String supplementary = "\uD800\uDC00";
        if (Integer.signum(bmp.compareTo(supplementary)) != 1
                || Integer.signum(UNSIGNED_UTF8.compare(bmp, supplementary)) != -1) {
            throw new IllegalStateException("Unicode ordering counterexample no longer reproduces");
        }
        VariantBuilder builder = new VariantBuilder();
        VariantObjectBuilder object = builder.startObject();
        object.appendKey(bmp);
        object.appendInt(1);
        object.appendKey(supplementary);
        object.appendInt(2);
        builder.endObject();
        Variant variant = builder.build();
        String metadataHex = HEX.formatHex(bytes(variant.getMetadataBuffer()));
        String valueHex = HEX.formatHex(bytes(variant.getValueBuffer()));
        if (!metadataHex.equals("0102000307ee8080f0908080")
                || !valueHex.equals("0202010000050a14020000001401000000")
                || variant.getFieldAtIndex(0).key.codePointAt(0) != 0x10000
                || variant.getFieldAtIndex(1).key.codePointAt(0) != 0xE000
                || variant.getFieldByKey(bmp).getInt() != 1
                || variant.getFieldByKey(supplementary).getInt() != 2) {
            throw new IllegalStateException("parquet-java Unicode deviation evidence changed");
        }
    }

    private static void verifyRealFourByteBoundaries() {
        String hugeKey = "k".repeat(0x1000000);
        VariantBuilder objectBuilder = new VariantBuilder();
        VariantObjectBuilder object = objectBuilder.startObject();
        object.appendKey(hugeKey);
        object.appendNull();
        objectBuilder.endObject();
        Variant objectVariant = objectBuilder.build();
        int metadataWidth = ((objectVariant.getMetadataBuffer().get(0) >>> 6) & 0x03) + 1;
        if (metadataWidth != 4 || objectVariant.getFieldByKey(hugeKey) == null) {
            throw new IllegalStateException("Real metadata 3-to-4-byte boundary failed");
        }

        byte[] payload = new byte[0x1000000 - 5];
        Arrays.fill(payload, (byte) 0xAB);
        VariantBuilder arrayBuilder = new VariantBuilder();
        VariantArrayBuilder array = arrayBuilder.startArray();
        array.appendBinary(ByteBuffer.wrap(payload));
        arrayBuilder.endArray();
        Variant arrayVariant = arrayBuilder.build();
        int valueHeader = (arrayVariant.getValueBuffer().get(0) & 0xFF) >>> 2;
        int offsetWidth = (valueHeader & 0x03) + 1;
        ByteBuffer decoded = arrayVariant.getElementAtIndex(0).getBinary();
        if (offsetWidth != 4
                || decoded.remaining() != payload.length
                || !Arrays.equals(payload, bytes(decoded))) {
            throw new IllegalStateException("Real value-offset 3-to-4-byte boundary failed");
        }
    }
}
