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

#include "benchmark/benchmark_suite.h"

#include <atomic>
#include <cstdint>
#include <iostream>
#include <map>
#include <memory>
#include <mutex>
#include <string>
#include <tuple>
#include <utility>
#include <vector>

#include "arrow/api.h"
#include "arrow/c/bridge.h"
#include "arrow/io/api.h"
#include "benchmark/benchmark_helpers.h"
#include "benchmark/cli_option_parsing.h"
#include "paimon/api.h"
#include "paimon/catalog/catalog.h"
#include "paimon/testing/utils/testharness.h"

#if __has_include("parquet/arrow/reader.h")
#include "parquet/arrow/reader.h"
#include "parquet/file_reader.h"
#define PAIMON_BENCHMARK_HAS_PARQUET_READER 1
#else
#define PAIMON_BENCHMARK_HAS_PARQUET_READER 0
#endif

namespace paimon::benchmark {

namespace {

constexpr int64_t kSourceBatchMaxRows = 4096;
constexpr int32_t kRowToBatchThreadNumber = 3;

struct BenchmarkCliOptions {
    std::string source_data_file;
    std::string source_table_path;
    std::vector<std::string> pk_columns;
    std::vector<std::pair<std::string, std::string>> extra_options;
};

struct SourceDataSpec {
    std::string format;
    std::string path;
};

BenchmarkCliOptions& MutableBenchmarkCliOptions() {
    static BenchmarkCliOptions options;
    return options;
}

const BenchmarkCliOptions& GetBenchmarkCliOptions() {
    return MutableBenchmarkCliOptions();
}

Status ParsePaimonBenchmarkCliArgsImpl(int32_t* argc, char** argv) {
    auto& options = MutableBenchmarkCliOptions();
    options = BenchmarkCliOptions{};
    const int32_t parsed_argc = *argc;
    int32_t write_index = 1;
    for (int32_t arg_index = 1; arg_index < parsed_argc; ++arg_index) {
        const std::string arg(argv[arg_index]);

        PAIMON_ASSIGN_OR_RAISE(bool is_parsed,
                               paimon::benchmark::ParseStringOptionArg(
                                   parsed_argc, argv, arg, "--paimon_source_data_file", &arg_index,
                                   &options.source_data_file));
        if (is_parsed) {
            continue;
        }
        PAIMON_ASSIGN_OR_RAISE(is_parsed, paimon::benchmark::ParseStringOptionArg(
                                              parsed_argc, argv, arg, "--paimon_source_table_path",
                                              &arg_index, &options.source_table_path));
        if (is_parsed) {
            continue;
        }
        PAIMON_ASSIGN_OR_RAISE(is_parsed, paimon::benchmark::ParseCommaSeparatedOptionArg(
                                              parsed_argc, argv, arg, "--paimon_pk_columns",
                                              &arg_index, &options.pk_columns));
        if (is_parsed) {
            continue;
        }
        PAIMON_ASSIGN_OR_RAISE(is_parsed, paimon::benchmark::ParseDelimitedRepeatableOptionArg(
                                              parsed_argc, argv, arg, "--paimon_option", &arg_index,
                                              &options.extra_options));
        if (is_parsed) {
            continue;
        }

        argv[write_index++] = argv[arg_index];
    }

    *argc = write_index;
    argv[write_index] = nullptr;
    return Status::OK();
}

bool HasHelpFlagImpl(int32_t argc, char** argv) {
    for (int32_t arg_index = 1; arg_index < argc; ++arg_index) {
        const std::string arg(argv[arg_index]);
        if (arg == "-h" || arg == "--help" || arg == "--help=true") {
            return true;
        }
    }
    return false;
}

void PrintPaimonBenchmarkCliHelpImpl() {
    std::cout
        << "Paimon benchmark custom options:\n"
        << "  --paimon_source_data_file=<path>\n"
        << "      Required. External source data file used to build benchmark data.\n"
        << "      Currently supports Parquet source files.\n"
        << "      Also supports: --paimon_source_data_file <path>\n"
        << "  --paimon_source_table_path=<path>\n"
        << "      Optional for BM_Read and BM_MOR_Read. If set, read directly from existing\n"
        << "      table path and skip source file loading and pre-write stage.\n"
        << "      Also supports: --paimon_source_table_path <path>\n"
        << "  --paimon_pk_columns=<col1,col2,...>\n"
        << "      Required by BM_PK_Write and BM_MOR_Read.\n"
        << "      Also supports: --paimon_pk_columns <col1,col2,...>\n"
        << "  --paimon_option=<key1>:<value1>;<key2>:<value2>\n"
        << "      Optional and repeatable. Pass through table options as-is.\n"
        << "      Default table file format is parquet; use file.format:<format> to override.\n"
        << "      Also supports: --paimon_option <key1>:<value1>;<key2>:<value2>\n"
        << "      Note: use quotes in shell, e.g. \"--paimon_option k1:v1;k2:v2\".\n"
        << "\n"
        << "Example:\n"
        << "  paimon-read-write-benchmark --paimon_source_data_file /path/data.parquet \\\n"
        << "      --paimon_pk_columns=id --paimon_option \"read.batch-size:8192\" \\\n"
        << "      --benchmark_filter=BM_Read\n"
        << std::endl;
}

Result<std::unique_ptr<paimon::test::UniqueTestDirectory>> CreateBenchmarkWorkspace() {
    auto workspace = paimon::test::UniqueTestDirectory::Create();
    if (workspace == nullptr) {
        return Status::Invalid("failed to create benchmark workspace");
    }
    return workspace;
}

uint64_t NextTableId() {
    static std::atomic<uint64_t> id{0};
    return ++id;
}

std::string RequirePath(const std::string& root_path, const std::string& db_name,
                        const std::string& table_name) {
    return root_path + "/" + db_name + ".db/" + table_name;
}

template <typename T>
Result<T> AddContext(paimon::Result<T>&& result, const std::string& context) {
    if (!result.ok()) {
        const Status status = result.status();
        return status.WithMessage(context, ": ", status.message());
    }
    return std::move(result).value();
}

Status AddContext(const paimon::Status& status, const std::string& context) {
    if (!status.ok()) {
        return status.WithMessage(context, ": ", status.message());
    }
    return Status::OK();
}

void SkipWithMessage(::benchmark::State& state, const std::string& message) {
    state.SkipWithError(message);
}

std::string GetConfiguredFileFormat() {
    std::string file_format = "parquet";
    for (const auto& kv : GetBenchmarkCliOptions().extra_options) {
        if (kv.first == paimon::Options::FILE_FORMAT) {
            file_format = kv.second;
        }
    }
    return file_format;
}

bool IsFileFormatSupported(const std::string& format) {
    if (format == "parquet") {
        return true;
    }
    if (format == "orc") {
#ifdef PAIMON_ENABLE_ORC
        return true;
#else
        return false;
#endif
    }
    return false;
}

void ApplyExtraOptions(std::map<std::string, std::string>* options) {
    for (const auto& kv : GetBenchmarkCliOptions().extra_options) {
        (*options)[kv.first] = kv.second;
    }
}

std::map<std::string, std::string> BuildOptions(const std::string& file_format) {
    std::map<std::string, std::string> options = {
        {paimon::Options::FILE_FORMAT, file_format},
    };
    ApplyExtraOptions(&options);
    return options;
}

std::map<std::string, std::string> BuildPkOptions(const std::string& file_format) {
    auto options = BuildOptions(file_format);
    options[paimon::Options::BUCKET] = "1";
    options[paimon::Options::MERGE_ENGINE] = "deduplicate";
    return options;
}

std::string GetSourceDataFilePath() {
    return GetBenchmarkCliOptions().source_data_file;
}

std::string GetSourceTablePath() {
    return GetBenchmarkCliOptions().source_table_path;
}

const std::vector<std::string>& GetPkColumns() {
    return GetBenchmarkCliOptions().pk_columns;
}

SourceDataSpec GetSourceDataSpec() {
    const std::string source_data_file_path = GetSourceDataFilePath();
    if (!source_data_file_path.empty()) {
        return {"parquet", source_data_file_path};
    }
    return {"", ""};
}

int64_t GetSourceBatchMaxRows() {
    return kSourceBatchMaxRows;
}

int32_t GetRowToBatchThreadNumber() {
    return kRowToBatchThreadNumber;
}

bool SupportsParquetSourceDataMode() {
#if PAIMON_BENCHMARK_HAS_PARQUET_READER
    return true;
#else
    return false;
#endif
}

bool SupportsSourceDataMode(const std::string& source_format) {
    if (source_format == "parquet") {
        return SupportsParquetSourceDataMode();
    }
    return false;
}

struct SourceDataMetadata {
    std::shared_ptr<arrow::Schema> schema;
    int64_t total_rows = 0;
    std::string format;
    std::string path;
};

#if PAIMON_BENCHMARK_HAS_PARQUET_READER
Result<std::unique_ptr<parquet::arrow::FileReader>> OpenParquetSourceReader(
    const std::string& path) {
    auto input = arrow::io::ReadableFile::Open(path);
    if (!input.ok()) {
        return Status::Invalid("open Parquet source failed: ", path, ", ",
                               input.status().ToString());
    }

    std::unique_ptr<parquet::arrow::FileReader> parquet_reader;
    const auto open_status = parquet::arrow::OpenFile(
        input.ValueUnsafe(), arrow::default_memory_pool(), &parquet_reader);
    if (!open_status.ok()) {
        return Status::Invalid("create Parquet reader failed: ", open_status.ToString());
    }
    parquet_reader->set_batch_size(GetSourceBatchMaxRows());
    return parquet_reader;
}
#endif

Result<SourceDataMetadata> LoadParquetSourceMetadata(const std::string& path) {
#if !PAIMON_BENCHMARK_HAS_PARQUET_READER
    return Status::Invalid(
        "Parquet source data mode requires parquet::arrow reader support in this build");
#else
    static SourceDataMetadata cache;
    static std::mutex cache_mutex;
    std::lock_guard<std::mutex> lock(cache_mutex);
    if (cache.path == path && cache.format == "parquet") {
        return cache;
    }

    PAIMON_ASSIGN_OR_RAISE(std::unique_ptr<parquet::arrow::FileReader> parquet_reader,
                           OpenParquetSourceReader(path));
    std::shared_ptr<arrow::Schema> schema;
    const auto schema_status = parquet_reader->GetSchema(&schema);
    if (!schema_status.ok()) {
        return Status::Invalid("read Parquet source schema failed: ", schema_status.ToString());
    }

    const int64_t total_rows = parquet_reader->parquet_reader()->metadata()->num_rows();
    if (total_rows <= 0) {
        return Status::Invalid("Parquet source is empty: ", path);
    }

    cache.schema = std::move(schema);
    cache.total_rows = total_rows;
    cache.format = "parquet";
    cache.path = path;
    return cache;
#endif
}

Result<SourceDataMetadata> LoadSourceDataMetadata(const SourceDataSpec& source_spec) {
    if (source_spec.format == "parquet") {
        return LoadParquetSourceMetadata(source_spec.path);
    }
    return Status::Invalid("unknown source format: ", source_spec.format);
}

std::shared_ptr<arrow::StructArray> BuildStructArrayFromRecordBatch(
    const std::shared_ptr<arrow::RecordBatch>& batch) {
    return std::make_shared<arrow::StructArray>(arrow::struct_(batch->schema()->fields()),
                                                batch->num_rows(), batch->columns());
}

Result<std::unique_ptr<paimon::RecordBatch>> MakeRecordBatch(
    const std::shared_ptr<arrow::StructArray>& arr) {
    ArrowArray c_array;
    if (!arrow::ExportArray(*arr, &c_array).ok()) {
        return Status::Invalid("failed to export arrow array");
    }
    paimon::RecordBatchBuilder builder(&c_array);
    return AddContext(builder.Finish(), "build paimon record batch");
}

Status EnsureTable(const std::string& root_path, const std::string& db_name,
                   const std::string& table_name, const std::map<std::string, std::string>& options,
                   const std::shared_ptr<arrow::Schema>& schema,
                   const std::vector<std::string>& primary_keys = {}) {
    PAIMON_ASSIGN_OR_RAISE(
        std::unique_ptr<paimon::Catalog> catalog,
        AddContext(paimon::Catalog::Create(root_path, options), "create catalog"));
    PAIMON_RETURN_NOT_OK(
        AddContext(catalog->CreateDatabase(db_name, options, true), "create database"));

    ArrowSchema c_schema;
    if (!arrow::ExportSchema(*schema, &c_schema).ok()) {
        return Status::Invalid("failed to export table schema");
    }
    PAIMON_RETURN_NOT_OK(
        AddContext(catalog->CreateTable(paimon::Identifier(db_name, table_name), &c_schema,
                                        /*partition_keys=*/{}, primary_keys, options,
                                        /*ignore_if_exists=*/false),
                   "create table"));
    return Status::OK();
}

Status WriteSourceDataToWriter(paimon::FileStoreWrite* writer, const SourceDataSpec& source_spec) {
    if (source_spec.format != "parquet") {
        return Status::Invalid("unknown source format: ", source_spec.format);
    }

#if !PAIMON_BENCHMARK_HAS_PARQUET_READER
    return Status::Invalid(
        "Parquet source data mode requires parquet::arrow reader support in this build");
#else
    PAIMON_ASSIGN_OR_RAISE(std::unique_ptr<parquet::arrow::FileReader> parquet_reader,
                           OpenParquetSourceReader(source_spec.path));
    std::unique_ptr<arrow::RecordBatchReader> batch_reader;
    const auto reader_status = parquet_reader->GetRecordBatchReader(&batch_reader);
    if (!reader_status.ok()) {
        return Status::Invalid("create Parquet source batch reader failed: ",
                               reader_status.ToString());
    }

    int64_t written_rows = 0;
    while (true) {
        std::shared_ptr<arrow::RecordBatch> record_batch;
        const auto read_status = batch_reader->ReadNext(&record_batch);
        if (!read_status.ok()) {
            return Status::Invalid("read Parquet source batch failed: ", read_status.ToString());
        }
        if (record_batch == nullptr) {
            break;
        }
        if (record_batch->num_rows() <= 0) {
            continue;
        }

        auto struct_array = BuildStructArrayFromRecordBatch(record_batch);
        PAIMON_ASSIGN_OR_RAISE(std::unique_ptr<paimon::RecordBatch> batch,
                               MakeRecordBatch(struct_array));
        PAIMON_RETURN_NOT_OK(AddContext(writer->Write(std::move(batch)), "write batch"));
        written_rows += record_batch->num_rows();
    }

    if (written_rows <= 0) {
        return Status::Invalid("source file has no non-empty data batches: ", source_spec.path);
    }
    return Status::OK();
#endif
}

Status WriteAndCommit(const std::string& table_path,
                      const std::map<std::string, std::string>& options,
                      const SourceDataSpec& source_spec) {
    paimon::WriteContextBuilder write_builder(table_path, "benchmark-writer");
    PAIMON_ASSIGN_OR_RAISE(
        std::unique_ptr<paimon::WriteContext> write_ctx,
        AddContext(write_builder.SetOptions(options).Finish(), "create write context"));
    PAIMON_ASSIGN_OR_RAISE(std::unique_ptr<paimon::FileStoreWrite> writer,
                           AddContext(paimon::FileStoreWrite::Create(std::move(write_ctx)),
                                      "create file store writer"));

    PAIMON_RETURN_NOT_OK(WriteSourceDataToWriter(writer.get(), source_spec));
    PAIMON_ASSIGN_OR_RAISE(std::vector<std::shared_ptr<paimon::CommitMessage>> messages,
                           AddContext(writer->PrepareCommit(), "prepare commit"));

    paimon::CommitContextBuilder commit_builder(table_path, "benchmark-writer");
    PAIMON_ASSIGN_OR_RAISE(
        std::unique_ptr<paimon::CommitContext> commit_ctx,
        AddContext(commit_builder.SetOptions(options).Finish(), "create commit context"));
    PAIMON_ASSIGN_OR_RAISE(
        std::unique_ptr<paimon::FileStoreCommit> committer,
        AddContext(paimon::FileStoreCommit::Create(std::move(commit_ctx)), "create committer"));
    PAIMON_RETURN_NOT_OK(AddContext(committer->Commit(messages), "commit write"));
    return Status::OK();
}

struct SharedReadTableCache {
    std::string key;
    std::unique_ptr<paimon::test::UniqueTestDirectory> workspace;
    std::string table_path;
    int64_t total_rows = 0;
};

struct SharedMorReadTableCache {
    std::string key;
    std::unique_ptr<paimon::test::UniqueTestDirectory> workspace;
    std::string table_path;
    int64_t total_rows = 0;
};

std::string BuildReadTableCacheKey(const std::string& file_format,
                                   const SourceDataSpec& source_spec) {
    return file_format + "|" + source_spec.format + "|" + source_spec.path + "|" +
           std::to_string(GetSourceBatchMaxRows());
}

std::string JoinColumns(const std::vector<std::string>& columns) {
    std::string joined;
    for (size_t i = 0; i < columns.size(); ++i) {
        if (i > 0) {
            joined.append(",");
        }
        joined.append(columns[i]);
    }
    return joined;
}

Result<const SharedMorReadTableCache*> GetOrCreateSharedMorReadTable(
    const std::string& file_format, const SourceDataSpec& source_spec) {
    static SharedMorReadTableCache cache;
    static std::mutex cache_mutex;

    const std::vector<std::string>& pk_columns = GetPkColumns();
    const std::string cache_key =
        BuildReadTableCacheKey(file_format, source_spec) + "|pk=" + JoinColumns(pk_columns);
    std::lock_guard<std::mutex> lock(cache_mutex);
    if (cache.workspace != nullptr && cache.key == cache_key) {
        std::cout << "[benchmark][mor-read] reuse_output_table_path=" << cache.table_path
                  << std::endl;
        return &cache;
    }

    auto options = BuildPkOptions(file_format);
    PAIMON_ASSIGN_OR_RAISE(const SourceDataMetadata source_metadata,
                           LoadSourceDataMetadata(source_spec));

    PAIMON_ASSIGN_OR_RAISE(std::unique_ptr<paimon::test::UniqueTestDirectory> workspace,
                           CreateBenchmarkWorkspace());
    const std::string db_name = "bench_db";
    const std::string table_name = "mor_read_shared_" + std::to_string(NextTableId());
    PAIMON_RETURN_NOT_OK(EnsureTable(workspace->Str(), db_name, table_name, options,
                                     source_metadata.schema,
                                     /*primary_keys=*/pk_columns));
    const std::string table_path = RequirePath(workspace->Str(), db_name, table_name);
    std::cout << "[benchmark][mor-read] create_shared_output_table_path=" << table_path
              << std::endl;
    PAIMON_RETURN_NOT_OK(WriteAndCommit(table_path, options, source_spec));

    cache.key = cache_key;
    cache.workspace = std::move(workspace);
    cache.table_path = table_path;
    cache.total_rows = source_metadata.total_rows;
    return &cache;
}

Result<const SharedReadTableCache*> GetOrCreateSharedReadTable(const std::string& file_format,
                                                               const SourceDataSpec& source_spec) {
    static SharedReadTableCache cache;
    static std::mutex cache_mutex;

    const std::string cache_key = BuildReadTableCacheKey(file_format, source_spec);
    std::lock_guard<std::mutex> lock(cache_mutex);
    if (cache.workspace != nullptr && cache.key == cache_key) {
        std::cout << "[benchmark][read] reuse_output_table_path=" << cache.table_path << std::endl;
        return &cache;
    }

    auto options = BuildOptions(file_format);
    PAIMON_ASSIGN_OR_RAISE(const SourceDataMetadata source_metadata,
                           LoadSourceDataMetadata(source_spec));

    PAIMON_ASSIGN_OR_RAISE(std::unique_ptr<paimon::test::UniqueTestDirectory> workspace,
                           CreateBenchmarkWorkspace());
    const std::string db_name = "bench_db";
    const std::string table_name = "read_shared_" + std::to_string(NextTableId());
    PAIMON_RETURN_NOT_OK(
        EnsureTable(workspace->Str(), db_name, table_name, options, source_metadata.schema));
    const std::string table_path = RequirePath(workspace->Str(), db_name, table_name);
    std::cout << "[benchmark][read] create_shared_output_table_path=" << table_path << std::endl;
    PAIMON_RETURN_NOT_OK(WriteAndCommit(table_path, options, source_spec));

    cache.key = cache_key;
    cache.workspace = std::move(workspace);
    cache.table_path = table_path;
    cache.total_rows = source_metadata.total_rows;
    return &cache;
}

Result<int64_t> ReadRows(const std::string& table_path,
                         const std::map<std::string, std::string>& options,
                         int32_t prefetch_parallel_num) {
    paimon::ScanContextBuilder scan_builder(table_path);
    PAIMON_ASSIGN_OR_RAISE(
        std::unique_ptr<paimon::ScanContext> scan_ctx,
        AddContext(scan_builder.SetOptions(options).Finish(), "create scan context"));
    PAIMON_ASSIGN_OR_RAISE(
        std::unique_ptr<paimon::TableScan> scanner,
        AddContext(paimon::TableScan::Create(std::move(scan_ctx)), "create scanner"));
    PAIMON_ASSIGN_OR_RAISE(std::shared_ptr<paimon::Plan> plan,
                           AddContext(scanner->CreatePlan(), "create plan"));

    paimon::ReadContextBuilder read_builder(table_path);
    constexpr int32_t kPrefetchBatchCount = 600;
    read_builder.SetOptions(options)
        .EnablePrefetch(true)
        .SetPrefetchBatchCount(kPrefetchBatchCount)
        .SetPrefetchMaxParallelNum(prefetch_parallel_num)
        .EnableMultiThreadRowToBatch(GetRowToBatchThreadNumber() > 1)
        .SetRowToBatchThreadNumber(GetRowToBatchThreadNumber());
    PAIMON_ASSIGN_OR_RAISE(std::unique_ptr<paimon::ReadContext> read_ctx,
                           AddContext(read_builder.Finish(), "create read context"));
    PAIMON_ASSIGN_OR_RAISE(
        std::unique_ptr<paimon::TableRead> reader,
        AddContext(paimon::TableRead::Create(std::move(read_ctx)), "create table reader"));
    PAIMON_ASSIGN_OR_RAISE(std::unique_ptr<paimon::BatchReader> batch_reader,
                           AddContext(reader->CreateReader(plan->Splits()), "create batch reader"));

    int64_t total_rows = 0;
    while (true) {
        PAIMON_ASSIGN_OR_RAISE(paimon::BatchReader::ReadBatch batch,
                               AddContext(batch_reader->NextBatch(), "read next batch"));
        if (paimon::BatchReader::IsEofBatch(batch)) {
            break;
        }
        auto& [array, schema] = batch;
        auto imported = arrow::ImportArray(array.get(), schema.get());
        if (!imported.ok()) {
            return Status::Invalid("import c data array failed: ", imported.status().ToString());
        }
        total_rows += imported.ValueUnsafe()->length();
    }

    return total_rows;
}

struct PreparedSourceData {
    std::shared_ptr<arrow::Schema> schema;
    int64_t total_rows = 0;
};

bool TryGetSourceSpec(::benchmark::State& state, SourceDataSpec* source_spec) {
    (void)state;
    *source_spec = GetSourceDataSpec();
    return true;
}

bool TryPrepareSourceData(::benchmark::State& state, const SourceDataSpec& source_spec,
                          PreparedSourceData* prepared) {
    auto source_metadata = LoadSourceDataMetadata(source_spec);
    if (!source_metadata.ok()) {
        SkipWithMessage(state, source_metadata.status().ToString());
        return false;
    }
    prepared->schema = source_metadata.value().schema;
    prepared->total_rows = source_metadata.value().total_rows;
    return true;
}

}  // namespace

Status ParsePaimonBenchmarkCliArgs(int* argc, char** argv) {
    auto parsed_argc = static_cast<int32_t>(*argc);
    PAIMON_RETURN_NOT_OK(ParsePaimonBenchmarkCliArgsImpl(&parsed_argc, argv));
    *argc = static_cast<int>(parsed_argc);
    return Status::OK();
}

bool HasHelpFlag(int32_t argc, char** argv) {
    return HasHelpFlagImpl(argc, argv);
}

void PrintPaimonBenchmarkCliHelp() {
    PrintPaimonBenchmarkCliHelpImpl();
}

void RunBMWrite(::benchmark::State& state) {
    const std::string file_format = GetConfiguredFileFormat();
    SourceDataSpec source_spec;
    if (!TryGetSourceSpec(state, &source_spec)) {
        return;
    }
    if (!BenchmarkHelpers::ValidateSourcePresenceOrSkip(
            state, source_spec.path, "--paimon_source_data_file is required", &SkipWithMessage)) {
        return;
    }
    if (!BenchmarkHelpers::ValidateSourceSupportOrSkip(state, source_spec.format,
                                                       SupportsSourceDataMode(source_spec.format),
                                                       &SkipWithMessage)) {
        return;
    }
    if (!BenchmarkHelpers::ValidateFileFormatOrSkip(
            state, file_format, IsFileFormatSupported(file_format), &SkipWithMessage)) {
        return;
    }

    auto options = BuildOptions(file_format);
    PreparedSourceData prepared;
    if (!TryPrepareSourceData(state, source_spec, &prepared)) {
        return;
    }
    auto workspace = CreateBenchmarkWorkspace();
    if (!workspace.ok()) {
        SkipWithMessage(state, workspace.status().ToString());
        return;
    }

    for (auto _ : state) {
        const std::string db_name = "bench_db";
        const std::string table_name = "write_" + std::to_string(NextTableId());
        const Status ensure_status =
            EnsureTable(workspace.value()->Str(), db_name, table_name, options, prepared.schema);
        if (!ensure_status.ok()) {
            SkipWithMessage(state, ensure_status.ToString());
            return;
        }
        const std::string table_path = RequirePath(workspace.value()->Str(), db_name, table_name);
        std::cout << "[benchmark][write] output_table_path=" << table_path << std::endl;
        const Status write_status = WriteAndCommit(table_path, options, source_spec);
        if (!write_status.ok()) {
            SkipWithMessage(state, write_status.ToString());
            return;
        }
    }

    state.SetItemsProcessed(state.iterations() * prepared.total_rows);
}

void RunBMRead(::benchmark::State& state) {
    const auto prefetch_parallel_num = static_cast<int32_t>(state.range(0));
    const std::string file_format = GetConfiguredFileFormat();
    const std::string source_table_path = GetSourceTablePath();
    SourceDataSpec source_spec;
    if (!TryGetSourceSpec(state, &source_spec)) {
        return;
    }
    if (!BenchmarkHelpers::ValidateFileFormatOrSkip(
            state, file_format, IsFileFormatSupported(file_format), &SkipWithMessage)) {
        return;
    }

    if (!BenchmarkHelpers::ValidatePrefetchParallelOrSkip(state, prefetch_parallel_num,
                                                          &SkipWithMessage)) {
        return;
    }

    auto options = BuildOptions(file_format);

    auto source_table_read_result = BenchmarkHelpers::TryRunSourceTableReadMode(
        state, "read", source_table_path,
        [&]() { return ReadRows(source_table_path, options, prefetch_parallel_num); });
    if (!source_table_read_result.ok()) {
        SkipWithMessage(state, source_table_read_result.status().ToString());
        return;
    }
    if (source_table_read_result.value()) {
        return;
    }

    if (!BenchmarkHelpers::ValidateSourcePresenceOrSkip(
            state, source_spec.path,
            "--paimon_source_data_file is required when --paimon_source_table_path is not set",
            &SkipWithMessage)) {
        return;
    }
    if (!BenchmarkHelpers::ValidateSourceSupportOrSkip(state, source_spec.format,
                                                       SupportsSourceDataMode(source_spec.format),
                                                       &SkipWithMessage)) {
        return;
    }

    auto shared_table = GetOrCreateSharedReadTable(file_format, source_spec);
    if (!shared_table.ok()) {
        SkipWithMessage(state, shared_table.status().ToString());
        return;
    }

    auto rows_read = BenchmarkHelpers::RunReadIterations(state, [&]() {
        return ReadRows(shared_table.value()->table_path, options, prefetch_parallel_num);
    });
    if (!rows_read.ok()) {
        SkipWithMessage(state, rows_read.status().ToString());
        return;
    }

    state.SetItemsProcessed(state.iterations() * rows_read.value());
}

void RunBMPkWrite(::benchmark::State& state) {
    const std::string file_format = GetConfiguredFileFormat();
    SourceDataSpec source_spec;
    if (!TryGetSourceSpec(state, &source_spec)) {
        return;
    }
    if (!BenchmarkHelpers::ValidateSourcePresenceOrSkip(
            state, source_spec.path, "--paimon_source_data_file is required", &SkipWithMessage)) {
        return;
    }
    if (!BenchmarkHelpers::ValidateSourceSupportOrSkip(state, source_spec.format,
                                                       SupportsSourceDataMode(source_spec.format),
                                                       &SkipWithMessage)) {
        return;
    }
    if (!BenchmarkHelpers::ValidateFileFormatOrSkip(
            state, file_format, IsFileFormatSupported(file_format), &SkipWithMessage)) {
        return;
    }
    const std::vector<std::string>& pk_columns = GetPkColumns();
    if (pk_columns.empty()) {
        SkipWithMessage(state, "--paimon_pk_columns is required for BM_PK_Write");
        return;
    }

    auto options = BuildPkOptions(file_format);
    PreparedSourceData prepared;
    if (!TryPrepareSourceData(state, source_spec, &prepared)) {
        return;
    }
    auto workspace = CreateBenchmarkWorkspace();
    if (!workspace.ok()) {
        SkipWithMessage(state, workspace.status().ToString());
        return;
    }

    for (auto _ : state) {
        const std::string db_name = "bench_db";
        const std::string table_name = "pk_write_" + std::to_string(NextTableId());
        const Status ensure_status =
            EnsureTable(workspace.value()->Str(), db_name, table_name, options, prepared.schema,
                        /*primary_keys=*/pk_columns);
        if (!ensure_status.ok()) {
            SkipWithMessage(state, ensure_status.ToString());
            return;
        }
        const std::string table_path = RequirePath(workspace.value()->Str(), db_name, table_name);
        std::cout << "[benchmark][pk-write] output_table_path=" << table_path << std::endl;
        const Status write_status = WriteAndCommit(table_path, options, source_spec);
        if (!write_status.ok()) {
            SkipWithMessage(state, write_status.ToString());
            return;
        }
    }

    state.SetItemsProcessed(state.iterations() * prepared.total_rows);
}

void RunBMMorRead(::benchmark::State& state) {
    const auto prefetch_parallel_num = static_cast<int32_t>(state.range(0));
    const std::string file_format = GetConfiguredFileFormat();
    const std::string source_table_path = GetSourceTablePath();
    SourceDataSpec source_spec;
    if (!TryGetSourceSpec(state, &source_spec)) {
        return;
    }
    if (!BenchmarkHelpers::ValidateFileFormatOrSkip(
            state, file_format, IsFileFormatSupported(file_format), &SkipWithMessage)) {
        return;
    }
    if (!BenchmarkHelpers::ValidatePrefetchParallelOrSkip(state, prefetch_parallel_num,
                                                          &SkipWithMessage)) {
        return;
    }

    const auto source_table_read_options = BuildOptions(file_format);
    auto source_table_read_result =
        BenchmarkHelpers::TryRunSourceTableReadMode(state, "mor-read", source_table_path, [&]() {
            return ReadRows(source_table_path, source_table_read_options, prefetch_parallel_num);
        });
    if (!source_table_read_result.ok()) {
        SkipWithMessage(state, source_table_read_result.status().ToString());
        return;
    }
    if (source_table_read_result.value()) {
        return;
    }

    if (!BenchmarkHelpers::ValidateSourcePresenceOrSkip(
            state, source_spec.path,
            "--paimon_source_data_file is required when --paimon_source_table_path is not set",
            &SkipWithMessage)) {
        return;
    }
    if (!BenchmarkHelpers::ValidateSourceSupportOrSkip(state, source_spec.format,
                                                       SupportsSourceDataMode(source_spec.format),
                                                       &SkipWithMessage)) {
        return;
    }
    if (GetPkColumns().empty()) {
        SkipWithMessage(state, "--paimon_pk_columns is required for BM_MOR_Read");
        return;
    }

    auto options = BuildPkOptions(file_format);
    auto shared_table = GetOrCreateSharedMorReadTable(file_format, source_spec);
    if (!shared_table.ok()) {
        SkipWithMessage(state, shared_table.status().ToString());
        return;
    }

    auto rows_read = BenchmarkHelpers::RunReadIterations(state, [&]() {
        return ReadRows(shared_table.value()->table_path, options, prefetch_parallel_num);
    });
    if (!rows_read.ok()) {
        SkipWithMessage(state, rows_read.status().ToString());
        return;
    }
    state.SetItemsProcessed(state.iterations() * rows_read.value());
}

}  // namespace paimon::benchmark
