/*
 * 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.
 */

// Smoke test for the assumptions parquet_format_benchmark.cpp is built on.
//
// The benchmark is only compiled under PAIMON_BUILD_BENCHMARKS, which CI does not set, so nothing
// there runs in CI. Every assumption it makes about the format layer - that a codec name is
// accepted, that a dictionary-encoded input array can be written, that a nested or high-precision
// column survives a round trip, that a predicate and a selection bitmap return the rows the
// benchmark asserts on, that the reader metrics it reports exist - is checked here instead, at a
// row count small enough to stay a test. A regression in any of them would otherwise surface as a
// benchmark that quietly measures the wrong thing.

#include <cstdint>
#include <map>
#include <memory>
#include <optional>
#include <string>
#include <utility>
#include <vector>

#include "arrow/api.h"
#include "arrow/array/concatenate.h"
#include "arrow/c/abi.h"
#include "arrow/c/bridge.h"
#include "arrow/c/helpers.h"
#include "gtest/gtest.h"
#include "paimon/common/utils/arrow/arrow_input_stream_adapter.h"
#include "paimon/common/utils/arrow/mem_utils.h"
#include "paimon/common/utils/checked_cast.h"
#include "paimon/common/utils/path_util.h"
#include "paimon/defs.h"
#include "paimon/format/format_writer.h"
#include "paimon/format/parquet/parquet_field_id_converter.h"
#include "paimon/format/parquet/parquet_file_batch_reader.h"
#include "paimon/format/parquet/parquet_format_defs.h"
#include "paimon/format/parquet/parquet_writer_builder.h"
#include "paimon/fs/file_system.h"
#include "paimon/memory/memory_pool.h"
#include "paimon/metrics.h"
#include "paimon/predicate/literal.h"
#include "paimon/predicate/predicate.h"
#include "paimon/predicate/predicate_builder.h"
#include "paimon/reader/batch_reader.h"
#include "paimon/result.h"
#include "paimon/status.h"
#include "paimon/testing/utils/testharness.h"
#include "paimon/utils/roaring_bitmap32.h"

namespace paimon::parquet {
namespace {

// Small enough to stay a test, large enough to span several batches and row groups.
constexpr int64_t kRows = 2'000;
constexpr int32_t kBatchSize = 256;
constexpr int64_t kRowGroupLength = 500;

std::shared_ptr<arrow::Field> MakeField(const std::string& name,
                                        const std::shared_ptr<arrow::DataType>& type,
                                        int32_t field_id) {
    return arrow::field(name, type,
                        arrow::KeyValueMetadata::Make({ParquetFieldIdConverter::PARQUET_FIELD_ID},
                                                      {std::to_string(field_id)}));
}

class ParquetFormatBenchmarkTest : public ::testing::Test {
 protected:
    void SetUp() override {
        dir_ = test::UniqueTestDirectory::Create();
        ASSERT_TRUE(dir_);
        fs_ = dir_->GetFileSystem();
        pool_ = GetArrowPool(GetDefaultPool());
    }

    std::string PathOf(const std::string& name) const {
        return PathUtil::JoinPath(dir_->Str(), name);
    }

    // Writes the same struct array `batch_count` times through the builder the benchmark uses.
    // More than one call matters for dictionary input: the benchmark always writes several
    // batches, and every batch after the first hands the writer the same dictionary again.
    Status Write(const std::string& path, const std::shared_ptr<arrow::Schema>& schema,
                 const std::shared_ptr<arrow::Array>& batch, const std::string& compression,
                 const std::map<std::string, std::string>& extra_options = {},
                 int32_t batch_count = 1) {
        return WriteBatches(path, schema,
                            std::vector<std::shared_ptr<arrow::Array>>(batch_count, batch),
                            compression, extra_options);
    }

    // The same, for a benchmark case whose batches are not identical - the changing-dictionary
    // write hands the writer a different dictionary every time.
    Status WriteBatches(const std::string& path, const std::shared_ptr<arrow::Schema>& schema,
                        const std::vector<std::shared_ptr<arrow::Array>>& batches,
                        const std::string& compression,
                        const std::map<std::string, std::string>& extra_options = {}) {
        std::map<std::string, std::string> options = extra_options;
        // emplace, not assignment: a caller that set its own row-group limit is testing that.
        options.emplace(PARQUET_WRITE_MAX_ROW_GROUP_LENGTH, std::to_string(kRowGroupLength));
        ParquetWriterBuilder writer_builder(schema, kBatchSize, options);
        PAIMON_ASSIGN_OR_RAISE(std::shared_ptr<OutputStream> out,
                               fs_->Create(path, /*overwrite=*/true));
        PAIMON_ASSIGN_OR_RAISE(std::unique_ptr<FormatWriter> writer,
                               writer_builder.Build(out, compression));
        for (const std::shared_ptr<arrow::Array>& batch : batches) {
            ArrowArray c_array;
            PAIMON_RETURN_NOT_OK_FROM_ARROW(arrow::ExportArray(*batch, &c_array));
            PAIMON_RETURN_NOT_OK(writer->AddBatch(&c_array));
        }
        PAIMON_RETURN_NOT_OK(writer->Finish());
        return out->Close();
    }

    // The expected value of a multi-batch write: one chunk per batch, in write order.
    static Result<std::shared_ptr<arrow::Array>> Concat(
        const std::vector<std::shared_ptr<arrow::Array>>& chunks) {
        PAIMON_ASSIGN_OR_RAISE_FROM_ARROW(std::shared_ptr<arrow::Array> concatenated,
                                          arrow::Concatenate(chunks));
        return concatenated;
    }

    // The same, when every batch carried the same array.
    static Result<std::shared_ptr<arrow::Array>> Repeat(const std::shared_ptr<arrow::Array>& array,
                                                        int32_t times) {
        return Concat(std::vector<std::shared_ptr<arrow::Array>>(times, array));
    }

    static Result<std::shared_ptr<arrow::Array>> MakeDictionary(
        const std::shared_ptr<arrow::Array>& indices, const std::shared_ptr<arrow::Array>& values) {
        PAIMON_ASSIGN_OR_RAISE_FROM_ARROW(std::shared_ptr<arrow::Array> array,
                                          arrow::DictionaryArray::FromArrays(indices, values));
        return array;
    }

    // `value_<index>`, the value MakeStringColumn emits at `index` in the benchmark.
    static std::string AlphabetValue(int64_t index) {
        return "value_" + std::to_string(index);
    }

    // Indices `(shift + i) % cardinality` over kRows, the index column every dictionary case here
    // is built from - the shape MakeDictionaryColumn gives a benchmark batch. `shift` cancels the
    // rotation MakeChangingDictionaryStringColumn applies to its alphabet.
    static Result<std::shared_ptr<arrow::Array>> MakeIndices(int64_t cardinality,
                                                             int64_t shift = 0) {
        arrow::Int32Builder builder;
        PAIMON_RETURN_NOT_OK_FROM_ARROW(builder.Reserve(kRows));
        for (int64_t i = 0; i < kRows; ++i) {
            builder.UnsafeAppend(static_cast<int32_t>((shift + i) % cardinality));
        }
        std::shared_ptr<arrow::Array> indices;
        PAIMON_RETURN_NOT_OK_FROM_ARROW(builder.Finish(&indices));
        return indices;
    }

    // The alphabet whose entry `j` is `value_<(j + rotation) % cardinality>`: the same
    // `cardinality` strings whatever the rotation, in a different order. Rotating it is how
    // MakeChangingDictionaryStringColumn gives every batch its own dictionary without changing the
    // data the batch decodes to.
    static Result<std::shared_ptr<arrow::Array>> MakeAlphabet(int64_t cardinality,
                                                              int64_t rotation = 0) {
        arrow::StringBuilder builder;
        for (int64_t i = 0; i < cardinality; ++i) {
            PAIMON_RETURN_NOT_OK_FROM_ARROW(
                builder.Append(AlphabetValue((rotation + i) % cardinality)));
        }
        std::shared_ptr<arrow::Array> alphabet;
        PAIMON_RETURN_NOT_OK_FROM_ARROW(builder.Finish(&alphabet));
        return alphabet;
    }

    // The flat column any of those batches has to decode back to, whatever the rotation.
    static Result<std::shared_ptr<arrow::Array>> MakeFlatAlphabetColumn(int64_t cardinality) {
        arrow::StringBuilder builder;
        PAIMON_RETURN_NOT_OK_FROM_ARROW(builder.Reserve(kRows));
        for (int64_t i = 0; i < kRows; ++i) {
            PAIMON_RETURN_NOT_OK_FROM_ARROW(builder.Append(AlphabetValue(i % cardinality)));
        }
        std::shared_ptr<arrow::Array> column;
        PAIMON_RETURN_NOT_OK_FROM_ARROW(builder.Finish(&column));
        return column;
    }

    struct ReadResult {
        int64_t rows = 0;
        uint64_t row_groups_total = 0;
        uint64_t row_groups_after_filter = 0;
        uint64_t batches = 0;
        // Every batch, imported and concatenated. Row counts alone would let a decoding bug
        // through, so the tests compare this against what was written.
        std::shared_ptr<arrow::Array> data;
    };

    // Reads the file back the way the benchmark does, reporting what the benchmark reports on.
    Result<ReadResult> Read(const std::string& path,
                            const std::shared_ptr<arrow::Schema>& read_schema,
                            const std::shared_ptr<Predicate>& predicate = nullptr,
                            const std::optional<RoaringBitmap32>& selection = std::nullopt,
                            const std::map<std::string, std::string>& read_options = {}) {
        PAIMON_ASSIGN_OR_RAISE(FileStatus file_status, fs_->GetFileStatus(path));
        PAIMON_ASSIGN_OR_RAISE(std::shared_ptr<InputStream> input, fs_->Open(path));
        auto in_stream =
            std::make_shared<ArrowInputStreamAdapter>(input, file_status.GetLen(), pool_);
        PAIMON_ASSIGN_OR_RAISE(std::unique_ptr<ParquetFileBatchReader> reader,
                               ParquetFileBatchReader::Create(
                                   std::move(in_stream), read_options, kBatchSize,
                                   /*file_metadata=*/nullptr, /*storage_read_bytes=*/nullptr, pool_,
                                   /*hints=*/std::nullopt));
        ArrowSchema c_schema;
        PAIMON_RETURN_NOT_OK_FROM_ARROW(arrow::ExportSchema(*read_schema, &c_schema));
        PAIMON_RETURN_NOT_OK(reader->SetReadSchema(&c_schema, predicate, selection));

        ReadResult result;
        std::vector<std::shared_ptr<arrow::Array>> chunks;
        while (true) {
            PAIMON_ASSIGN_OR_RAISE(BatchReader::ReadBatch batch, reader->NextBatch());
            if (BatchReader::IsEofBatch(batch)) {
                break;
            }
            // ImportArray takes ownership of both C structs, so nothing is released by hand here.
            PAIMON_ASSIGN_OR_RAISE_FROM_ARROW(
                std::shared_ptr<arrow::Array> chunk,
                arrow::ImportArray(batch.first.get(), batch.second.get()));
            result.rows += chunk->length();
            chunks.push_back(std::move(chunk));
        }
        if (!chunks.empty()) {
            PAIMON_ASSIGN_OR_RAISE_FROM_ARROW(result.data, arrow::Concatenate(chunks));
        }

        std::shared_ptr<Metrics> metrics = reader->GetReaderMetrics();
        PAIMON_ASSIGN_OR_RAISE(result.row_groups_total,
                               metrics->GetCounter(ParquetMetrics::READ_ROW_GROUPS_TOTAL));
        PAIMON_ASSIGN_OR_RAISE(result.row_groups_after_filter,
                               metrics->GetCounter(ParquetMetrics::READ_ROW_GROUPS_AFTER_FILTER));
        PAIMON_ASSIGN_OR_RAISE(result.batches,
                               metrics->GetCounter(ParquetMetrics::READ_BATCH_COUNT));
        reader->Close();
        return result;
    }

    static Result<std::shared_ptr<arrow::Array>> Wrap(
        const std::shared_ptr<arrow::Schema>& schema,
        const std::vector<std::shared_ptr<arrow::Array>>& columns) {
        PAIMON_ASSIGN_OR_RAISE_FROM_ARROW(std::shared_ptr<arrow::StructArray> array,
                                          arrow::StructArray::Make(columns, schema->fields()));
        return checked_pointer_cast<arrow::Array>(array);
    }

    std::unique_ptr<test::UniqueTestDirectory> dir_;
    std::shared_ptr<FileSystem> fs_;
    std::shared_ptr<arrow::MemoryPool> pool_;
};

// Every codec name the benchmark registers has to be one Parquet accepts. "lz4" is the trap this
// guards: it resolves to arrow's LZ4_FRAME, which parquet::IsCodecSupported rejects, and the
// failure only shows up once a column chunk is actually written.
TEST_F(ParquetFormatBenchmarkTest, RegisteredCodecsWrite) {
    std::shared_ptr<arrow::Schema> schema = arrow::schema({MakeField("id", arrow::int64(), 0)});
    arrow::Int64Builder builder;
    ASSERT_TRUE(builder.Reserve(kRows).ok());
    for (int64_t i = 0; i < kRows; ++i) {
        builder.UnsafeAppend(i);
    }
    std::shared_ptr<arrow::Array> ids;
    ASSERT_TRUE(builder.Finish(&ids).ok());
    ASSERT_OK_AND_ASSIGN(std::shared_ptr<arrow::Array> batch, Wrap(schema, {ids}));

    for (const std::string& codec :
         {"none", "snappy", "gzip", "brotli", "zstd", "lz4_raw", "lz4_hadoop"}) {
        const std::string path = PathOf("codec_" + codec + ".parquet");
        ASSERT_OK(Write(path, schema, batch, codec)) << "codec " << codec;
        ASSERT_OK_AND_ASSIGN(ReadResult result, Read(path, schema));
        EXPECT_EQ(kRows, result.rows) << "codec " << codec;
        ASSERT_TRUE(result.data);
        EXPECT_TRUE(result.data->Equals(*batch)) << "codec " << codec;
    }

    // The name the benchmark deliberately does not register still has to be rejected; if arrow
    // ever starts accepting it, the comment explaining its absence is stale.
    EXPECT_FALSE(Write(PathOf("codec_lz4.parquet"), schema, batch, "lz4").ok());
}

// A dictionary-encoded input array must reach the writer intact. VARCHAR takes arrow's direct
// write path and INT32 gets densified first; both have to produce a readable file whose logical
// values match the flat equivalent.
TEST_F(ParquetFormatBenchmarkTest, DictionaryInputRoundTrip) {
    constexpr int64_t kCardinality = 8;
    ASSERT_OK_AND_ASSIGN(std::shared_ptr<arrow::Array> indices, MakeIndices(kCardinality));
    ASSERT_OK_AND_ASSIGN(std::shared_ptr<arrow::Array> string_dict, MakeAlphabet(kCardinality));
    // The flat array the dictionary-encoded input has to decode back to.
    ASSERT_OK_AND_ASSIGN(std::shared_ptr<arrow::Array> flat_string_column,
                         MakeFlatAlphabetColumn(kCardinality));

    // The INT32 dictionary holds the same `i * 7` values MakeInt32Column emits inline, which is
    // what makes the two benchmark cases comparable.
    arrow::Int32Builder int_values;
    arrow::Int32Builder flat_ints;
    for (int64_t i = 0; i < kCardinality; ++i) {
        ASSERT_TRUE(int_values.Append(static_cast<int32_t>(i * 7)).ok());
    }
    for (int64_t i = 0; i < kRows; ++i) {
        ASSERT_TRUE(flat_ints.Append(static_cast<int32_t>((i % kCardinality) * 7)).ok());
    }
    std::shared_ptr<arrow::Array> int_dict;
    std::shared_ptr<arrow::Array> flat_int_column;
    ASSERT_TRUE(int_values.Finish(&int_dict).ok());
    ASSERT_TRUE(flat_ints.Finish(&flat_int_column).ok());

    struct Case {
        const char* name;
        std::shared_ptr<arrow::Array> dictionary;
        std::shared_ptr<arrow::DataType> read_type;
        std::shared_ptr<arrow::Array> flat;
    };
    // The benchmark always writes several batches, so the writer sees the same dictionary more
    // than once.
    constexpr int32_t kBatches = 3;
    for (const Case& c : {Case{"string", string_dict, arrow::utf8(), flat_string_column},
                          Case{"int32", int_dict, arrow::int32(), flat_int_column}}) {
        ASSERT_OK_AND_ASSIGN(std::shared_ptr<arrow::Array> dictionary_array,
                             MakeDictionary(indices, c.dictionary));
        std::shared_ptr<arrow::Schema> write_schema =
            arrow::schema({MakeField("v", dictionary_array->type(), 0)});
        ASSERT_OK_AND_ASSIGN(std::shared_ptr<arrow::Array> batch,
                             Wrap(write_schema, {dictionary_array}));
        const std::string path = PathOf(std::string("dict_") + c.name + ".parquet");
        ASSERT_OK(Write(path, write_schema, batch, "zstd", /*extra_options=*/{}, kBatches))
            << c.name;

        // Parquet has no dictionary type: the column comes back as its value type either way, and
        // has to carry the values the flat equivalent would have.
        std::shared_ptr<arrow::Schema> read_schema =
            arrow::schema({MakeField("v", c.read_type, 0)});
        ASSERT_OK_AND_ASSIGN(ReadResult result, Read(path, read_schema));
        EXPECT_EQ(kRows * kBatches, result.rows) << c.name;
        ASSERT_TRUE(result.data);
        ASSERT_OK_AND_ASSIGN(std::shared_ptr<arrow::Array> expected, Repeat(c.flat, kBatches));
        std::shared_ptr<arrow::Array> actual =
            checked_pointer_cast<arrow::StructArray>(result.data)->field(0);
        EXPECT_TRUE(actual->Equals(*expected)) << c.name;
    }
}

// BM_ParquetWrite_DictionaryStringIntoStringSchema and its Changing... counterpart are only worth
// running as a pair if the pair measures two different things: one dictionary for the whole file
// against one per batch, where a Parquet column chunk's single dictionary forces the writer to
// plain encoding partway through. If that stopped happening the two would quietly measure the same
// work, so both halves are pinned here. The column shapes are rebuilt rather than taken from the
// benchmark, which this target does not compile in: the premise is what is pinned, not the
// factories.
//
// The two cases write *identical data* - same values, same order, same widths - and differ only in
// whether each batch's dictionary is a rotation of the last. That is what makes the benchmark delta
// attributable to the fallback, so this test asserts both halves against one expected column.
//
// The fallback is asserted through the reader's passthrough gate, which is the definition of
// "every data page dictionary-encoded" and decides whether a compacted file can be forwarded again
// on the next round. Its writer side, counted in pages, is
// ParquetFormatWriterTest.TestWriteDictionaryChangingAcrossBatches.
TEST_F(ParquetFormatBenchmarkTest, ChangingDictionaryInputFallsBackToPlain) {
    constexpr int64_t kCardinality = 8;
    constexpr int32_t kBatches = 3;
    // Deliberately not a divisor of kRows, so a row group straddles two batches. A limit that
    // divided the batch size would give every row group exactly one dictionary, the changing case
    // could never fall back, and this test would pass while asserting nothing.
    constexpr int64_t kStraddlingRowGroupLength = 700;

    // Plain STRING, as a compaction rewrite builds it from the table's logical schema. The batches
    // carry the encoding the schema does not declare, which the writer recovers from their layout.
    std::shared_ptr<arrow::Schema> write_schema = arrow::schema({MakeField("v", arrow::utf8(), 0)});
    // One expected column for both cases, which is the point: rotating a dictionary is not
    // supposed to change what the file holds.
    ASSERT_OK_AND_ASSIGN(std::shared_ptr<arrow::Array> expected_chunk,
                         MakeFlatAlphabetColumn(kCardinality));
    ASSERT_OK_AND_ASSIGN(std::shared_ptr<arrow::Array> expected, Repeat(expected_chunk, kBatches));

    struct Case {
        const char* name;
        // Whether each batch rotates the dictionary, which is the only difference between the two
        // column factories the benchmark pair uses.
        bool changing;
        // Whether the reader's gate still accepts the file, which is exactly whether the writer
        // kept the column dictionary-encoded end to end.
        bool expect_dictionary;
    };
    for (const Case& c : {Case{"shared", false, true}, Case{"changing", true, false}}) {
        std::vector<std::shared_ptr<arrow::Array>> batches;
        for (int32_t batch = 0; batch < kBatches; ++batch) {
            // Rotating the alphabet and shifting the indices back by the same amount cancels, so
            // every batch decodes to `expected_chunk` while presenting a dictionary the writer has
            // not seen before.
            const int64_t rotation = c.changing ? batch % kCardinality : 0;
            ASSERT_OK_AND_ASSIGN(std::shared_ptr<arrow::Array> indices,
                                 MakeIndices(kCardinality, kCardinality - rotation));
            ASSERT_OK_AND_ASSIGN(std::shared_ptr<arrow::Array> alphabet,
                                 MakeAlphabet(kCardinality, rotation));
            ASSERT_OK_AND_ASSIGN(std::shared_ptr<arrow::Array> column,
                                 MakeDictionary(indices, alphabet));
            ASSERT_OK_AND_ASSIGN(
                std::shared_ptr<arrow::Array> encoded,
                Wrap(arrow::schema({write_schema->field(0)->WithType(column->type())}), {column}));
            batches.push_back(std::move(encoded));
        }

        const std::string path = PathOf(std::string("changing_dict_") + c.name + ".parquet");
        ASSERT_OK(WriteBatches(
            path, write_schema, batches, "zstd",
            {{PARQUET_WRITE_MAX_ROW_GROUP_LENGTH, std::to_string(kStraddlingRowGroupLength)}}))
            << c.name;

        // Values first: the fallback trades encoding and size, never correctness.
        ASSERT_OK_AND_ASSIGN(ReadResult result, Read(path, write_schema));
        EXPECT_EQ(kRows * kBatches, result.rows) << c.name;
        ASSERT_TRUE(result.data) << c.name;
        EXPECT_TRUE(
            checked_pointer_cast<arrow::StructArray>(result.data)->field(0)->Equals(*expected))
            << c.name;

        // Then the encoding, read back through the gate that decides it.
        ASSERT_OK_AND_ASSIGN(
            ReadResult encoded_result,
            Read(path, write_schema, /*predicate=*/nullptr, /*selection=*/std::nullopt,
                 {{PARQUET_READ_ENABLE_DICTIONARY_PASSTHROUGH, "true"}}));
        ASSERT_TRUE(encoded_result.data) << c.name;
        std::shared_ptr<arrow::Array> column =
            checked_pointer_cast<arrow::StructArray>(encoded_result.data)->field(0);
        EXPECT_EQ(c.expect_dictionary, column->type_id() == arrow::Type::DICTIONARY)
            << c.name << ": " << column->type()->ToString();
    }
}

// DECIMAL precision selects the Parquet physical type, and precision 38 is the only one that
// reaches FIXED_LEN_BYTE_ARRAY. The benchmark sweeps all three on both sides, so all three have
// to survive a round trip with their type intact.
TEST_F(ParquetFormatBenchmarkTest, DecimalPrecisionRoundTrip) {
    for (int32_t precision : {9, 18, 38}) {
        std::shared_ptr<arrow::DataType> type = arrow::decimal128(precision, 4);
        std::shared_ptr<arrow::Schema> schema = arrow::schema({MakeField("amount", type, 0)});
        arrow::Decimal128Builder builder(type);
        ASSERT_TRUE(builder.Reserve(kRows).ok());
        for (int64_t i = 0; i < kRows; ++i) {
            ASSERT_TRUE(builder.Append(arrow::Decimal128(i)).ok());
        }
        std::shared_ptr<arrow::Array> amounts;
        ASSERT_TRUE(builder.Finish(&amounts).ok());
        ASSERT_OK_AND_ASSIGN(std::shared_ptr<arrow::Array> batch, Wrap(schema, {amounts}));

        const std::string path = PathOf("decimal_" + std::to_string(precision) + ".parquet");
        ASSERT_OK(Write(path, schema, batch, "zstd")) << "precision " << precision;
        ASSERT_OK_AND_ASSIGN(ReadResult result, Read(path, schema));
        EXPECT_EQ(kRows, result.rows) << "precision " << precision;
        ASSERT_TRUE(result.data);
        EXPECT_TRUE(result.data->type()->field(0)->type()->Equals(*type))
            << "precision " << precision;
        EXPECT_TRUE(result.data->Equals(*batch)) << "precision " << precision;
    }
}

// The nested fixture the benchmark reads is only meaningful if LIST and MAP survive the round
// trip with the shape the read schema asks for.
TEST_F(ParquetFormatBenchmarkTest, NestedRoundTrip) {
    constexpr int32_t kEntries = 4;
    auto list_values = std::make_shared<arrow::Int64Builder>();
    arrow::ListBuilder list_builder(arrow::default_memory_pool(), list_values,
                                    arrow::list(arrow::int64()));
    auto key_builder = std::make_shared<arrow::StringBuilder>();
    auto item_builder = std::make_shared<arrow::Int64Builder>();
    arrow::MapBuilder map_builder(arrow::default_memory_pool(), key_builder, item_builder,
                                  arrow::map(arrow::utf8(), arrow::int64()));
    for (int64_t i = 0; i < kRows; ++i) {
        ASSERT_TRUE(list_builder.Append().ok());
        ASSERT_TRUE(map_builder.Append().ok());
        for (int32_t j = 0; j < kEntries; ++j) {
            ASSERT_TRUE(list_values->Append(i + j).ok());
            ASSERT_TRUE(key_builder->Append("key_" + std::to_string(j)).ok());
            ASSERT_TRUE(item_builder->Append(i + j).ok());
        }
    }
    std::shared_ptr<arrow::Array> tags;
    std::shared_ptr<arrow::Array> attrs;
    ASSERT_TRUE(list_builder.Finish(&tags).ok());
    ASSERT_TRUE(map_builder.Finish(&attrs).ok());

    std::shared_ptr<arrow::Schema> schema =
        arrow::schema({MakeField("tags", arrow::list(arrow::int64()), 0),
                       MakeField("attrs", arrow::map(arrow::utf8(), arrow::int64()), 1)});
    ASSERT_OK_AND_ASSIGN(std::shared_ptr<arrow::Array> batch, Wrap(schema, {tags, attrs}));
    const std::string path = PathOf("nested.parquet");
    ASSERT_OK(Write(path, schema, batch, "zstd"));

    ASSERT_OK_AND_ASSIGN(ReadResult result, Read(path, schema));
    EXPECT_EQ(kRows, result.rows);
    ASSERT_TRUE(result.data);
    EXPECT_TRUE(result.data->Equals(*batch));

    // Each nested column also has to be readable on its own, which is what the projected nested
    // cases do.
    for (const std::string& column : {"tags", "attrs"}) {
        std::shared_ptr<arrow::Schema> projected = arrow::schema({schema->GetFieldByName(column)});
        ASSERT_OK_AND_ASSIGN(ReadResult projected_result, Read(path, projected));
        EXPECT_EQ(kRows, projected_result.rows) << "column " << column;
    }
}

// The filtered and skip-heavy cases assert on row counts, so those counts have to mean what the
// benchmark assumes: a predicate keeps at least the matching rows and no more than the row groups
// that could hold them, and a selection bitmap keeps at least the rows it selected.
TEST_F(ParquetFormatBenchmarkTest, FilteredAndBitmapRowCounts) {
    std::shared_ptr<arrow::Schema> schema = arrow::schema({MakeField("id", arrow::int64(), 0)});
    arrow::Int64Builder builder;
    ASSERT_TRUE(builder.Reserve(kRows).ok());
    for (int64_t i = 0; i < kRows; ++i) {
        builder.UnsafeAppend(i);
    }
    std::shared_ptr<arrow::Array> ids;
    ASSERT_TRUE(builder.Finish(&ids).ok());
    ASSERT_OK_AND_ASSIGN(std::shared_ptr<arrow::Array> batch, Wrap(schema, {ids}));
    const std::string path = PathOf("filtered.parquet");
    ASSERT_OK(Write(path, schema, batch, "zstd"));

    ASSERT_OK_AND_ASSIGN(ReadResult full, Read(path, schema));
    EXPECT_EQ(kRows, full.rows);
    EXPECT_EQ(static_cast<uint64_t>(kRows / kRowGroupLength), full.row_groups_total);
    EXPECT_EQ(full.row_groups_total, full.row_groups_after_filter);
    EXPECT_GT(full.batches, 0u);

    // `id` is ordered, so row-group statistics alone must discard everything past the threshold.
    // This is the bound BM_ParquetRead_Filtered asserts on.
    constexpr int64_t kThreshold = 300;
    std::shared_ptr<Predicate> predicate = PredicateBuilder::LessThan(
        /*field_index=*/0, /*field_name=*/"id", FieldType::BIGINT, Literal(kThreshold));
    ASSERT_OK_AND_ASSIGN(ReadResult filtered, Read(path, schema, predicate));
    EXPECT_GE(filtered.rows, kThreshold);
    EXPECT_LE(filtered.rows, kRowGroupLength);
    EXPECT_LT(filtered.row_groups_after_filter, filtered.row_groups_total);

    // Selection is not precise, so the bitmap is a lower bound on what comes back.
    RoaringBitmap32 bitmap;
    int64_t selected = 0;
    for (int64_t row = 0; row < kRows; row += 64) {
        bitmap.Add(static_cast<int32_t>(row));
        ++selected;
    }
    ASSERT_OK_AND_ASSIGN(ReadResult skipped, Read(path, schema, /*predicate=*/nullptr, bitmap));
    EXPECT_GE(skipped.rows, selected);
    EXPECT_LE(skipped.rows, kRows);
}

// The encoding case compares a dictionary-encoded file against a plain one, which is only a
// comparison if both files read back identically.
TEST_F(ParquetFormatBenchmarkTest, PlainAndDictionaryFilesAgree) {
    std::shared_ptr<arrow::Schema> schema = arrow::schema({MakeField("name", arrow::utf8(), 0)});
    arrow::StringBuilder builder;
    ASSERT_TRUE(builder.Reserve(kRows).ok());
    for (int64_t i = 0; i < kRows; ++i) {
        ASSERT_TRUE(builder.Append("value_" + std::to_string(i % 16)).ok());
    }
    std::shared_ptr<arrow::Array> names;
    ASSERT_TRUE(builder.Finish(&names).ok());
    ASSERT_OK_AND_ASSIGN(std::shared_ptr<arrow::Array> batch, Wrap(schema, {names}));

    const std::string dict_path = PathOf("encoding_dict.parquet");
    const std::string plain_path = PathOf("encoding_plain.parquet");
    ASSERT_OK(Write(dict_path, schema, batch, "zstd"));
    std::map<std::string, std::string> plain_options;
    plain_options[PARQUET_ENABLE_DICTIONARY] = "false";
    ASSERT_OK(Write(plain_path, schema, batch, "zstd", plain_options));

    ASSERT_OK_AND_ASSIGN(ReadResult dict_result, Read(dict_path, schema));
    ASSERT_OK_AND_ASSIGN(ReadResult plain_result, Read(plain_path, schema));
    EXPECT_EQ(kRows, dict_result.rows);
    EXPECT_EQ(dict_result.rows, plain_result.rows);
    EXPECT_EQ(dict_result.row_groups_total, plain_result.row_groups_total);
    ASSERT_TRUE(dict_result.data);
    ASSERT_TRUE(plain_result.data);
    EXPECT_TRUE(dict_result.data->Equals(*batch));
    EXPECT_TRUE(plain_result.data->Equals(*batch));
}

// BM_ParquetWrite_MemoryThreshold rests on one assumption: that a small
// parquet.writer.max.memory.use actually makes ParquetFormatWriter cut extra row groups. This
// covers the mechanism on both input shapes that case can present it with, plain and
// dictionary-encoded, with the row-count limit raised out of the way so the byte threshold is the
// only thing that can flush.
//
// It does not cover the benchmark's own 512 KiB setting: reaching that with cardinality-10
// dictionary data takes the 500K to 2M rows the benchmark writes, which is not a unit test. What
// confirms that setting is the benchmark's own row_groups counter reading more than 1.
TEST_F(ParquetFormatBenchmarkTest, MemoryThresholdFlushesRowGroups) {
    constexpr int32_t kBatches = 8;
    constexpr int64_t kDictCardinality = 10;

    arrow::StringBuilder plain_builder;
    ASSERT_TRUE(plain_builder.Reserve(kRows).ok());
    for (int64_t i = 0; i < kRows; ++i) {
        ASSERT_TRUE(plain_builder.Append("value_" + std::to_string(i)).ok());
    }
    std::shared_ptr<arrow::Array> plain_column;
    ASSERT_TRUE(plain_builder.Finish(&plain_column).ok());

    // The shape BM_ParquetWrite_MemoryThreshold writes: low-cardinality dictionary input.
    arrow::StringBuilder dict_values;
    for (int64_t i = 0; i < kDictCardinality; ++i) {
        ASSERT_TRUE(dict_values.Append("value_" + std::to_string(i)).ok());
    }
    std::shared_ptr<arrow::Array> dict_value_column;
    ASSERT_TRUE(dict_values.Finish(&dict_value_column).ok());
    arrow::Int32Builder dict_indices;
    ASSERT_TRUE(dict_indices.Reserve(kRows).ok());
    for (int64_t i = 0; i < kRows; ++i) {
        dict_indices.UnsafeAppend(static_cast<int32_t>(i % kDictCardinality));
    }
    std::shared_ptr<arrow::Array> index_column;
    ASSERT_TRUE(dict_indices.Finish(&index_column).ok());
    ASSERT_OK_AND_ASSIGN(std::shared_ptr<arrow::Array> dict_column,
                         MakeDictionary(index_column, dict_value_column));

    struct Case {
        const char* name;
        std::shared_ptr<arrow::Array> column;
    };
    for (const Case& c : {Case{"plain", plain_column}, Case{"dictionary", dict_column}}) {
        std::shared_ptr<arrow::Schema> write_schema =
            arrow::schema({MakeField("name", c.column->type(), 0)});
        // Parquet stores a dictionary column as its value type, so both read back as UTF8.
        std::shared_ptr<arrow::Schema> read_schema =
            arrow::schema({MakeField("name", arrow::utf8(), 0)});
        ASSERT_OK_AND_ASSIGN(std::shared_ptr<arrow::Array> batch, Wrap(write_schema, {c.column}));

        std::map<std::string, std::string> options;
        options[PARQUET_WRITE_MAX_ROW_GROUP_LENGTH] = std::to_string(kRows * kBatches * 10);

        options[PARQUET_WRITER_MAX_MEMORY_USE] = std::to_string(uint64_t{8} * 1024);
        const std::string small_path =
            PathOf(std::string("threshold_small_") + c.name + ".parquet");
        ASSERT_OK(Write(small_path, write_schema, batch, "zstd", options, kBatches)) << c.name;
        ASSERT_OK_AND_ASSIGN(ReadResult small, Read(small_path, read_schema));
        EXPECT_EQ(kRows * kBatches, small.rows) << c.name;
        EXPECT_GT(small.row_groups_total, 1u)
            << c.name << ": byte threshold never triggered a flush";

        options[PARQUET_WRITER_MAX_MEMORY_USE] =
            std::to_string(DEFAULT_PARQUET_WRITER_MAX_MEMORY_USE);
        const std::string large_path =
            PathOf(std::string("threshold_large_") + c.name + ".parquet");
        ASSERT_OK(Write(large_path, write_schema, batch, "zstd", options, kBatches)) << c.name;
        ASSERT_OK_AND_ASSIGN(ReadResult large, Read(large_path, read_schema));
        EXPECT_EQ(kRows * kBatches, large.rows) << c.name;
        EXPECT_EQ(1u, large.row_groups_total) << c.name;

        // Row-group boundaries must not change the data.
        ASSERT_TRUE(small.data) << c.name;
        ASSERT_TRUE(large.data) << c.name;
        EXPECT_TRUE(small.data->Equals(*large.data)) << c.name;
    }
}

}  // namespace
}  // namespace paimon::parquet
