// Copyright 2023 Greptime Team
//
// Licensed 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.

//! Option keys for the mito engine.
//! We define them in this mod so the create parser can use it to validate table options.

/// Option key for all WAL options.
pub use common_wal::options::WAL_OPTIONS_KEY;
/// Option key for append mode.
pub const APPEND_MODE_KEY: &str = "append_mode";
/// Option key for the per-region write buffer size.
pub const WRITE_BUFFER_SIZE_KEY: &str = "write_buffer_size";
/// Option key for merge mode.
pub const MERGE_MODE_KEY: &str = "merge_mode";
/// Option key for TTL(time-to-live)
pub const TTL_KEY: &str = "ttl";
/// Option key for the per-table auto flush interval.
pub const AUTO_FLUSH_INTERVAL_KEY: &str = "auto_flush_interval";
/// Option key for snapshot read.
pub const SNAPSHOT_READ: &str = "snapshot_read";
/// Option key for compaction type.
pub const COMPACTION_TYPE: &str = "compaction.type";
/// Option key for forcing compaction options override.
pub const COMPACTION_OVERRIDE: &str = "compaction.override";
/// TWCS compaction strategy.
pub const COMPACTION_TYPE_TWCS: &str = "twcs";
/// Option key for twcs min file num to trigger a compaction.
pub const TWCS_TRIGGER_FILE_NUM: &str = "compaction.twcs.trigger_file_num";
/// Option key for twcs max output file size.
pub const TWCS_MAX_OUTPUT_FILE_SIZE: &str = "compaction.twcs.max_output_file_size";
/// Option key for twcs time window.
pub const TWCS_TIME_WINDOW: &str = "compaction.twcs.time_window";
/// Option key for twcs remote compaction.
pub const TWCS_REMOTE_COMPACTION: &str = "compaction.twcs.remote_compaction";
/// Option key for twcs fallback to local.
pub const TWCS_FALLBACK_TO_LOCAL: &str = "compaction.twcs.fallback_to_local";
/// Option key for memtable type.
pub const MEMTABLE_TYPE: &str = "memtable.type";
/// Option key for bulk memtable merge threshold.
pub const MEMTABLE_BULK_MERGE_THRESHOLD: &str = "memtable.bulk.merge_threshold";
/// Option key for bulk memtable encode row threshold.
pub const MEMTABLE_BULK_ENCODE_ROW_THRESHOLD: &str = "memtable.bulk.encode_row_threshold";
/// Option key for bulk memtable encode bytes threshold.
pub const MEMTABLE_BULK_ENCODE_BYTES_THRESHOLD: &str = "memtable.bulk.encode_bytes_threshold";
/// Option key for bulk memtable max merge groups.
pub const MEMTABLE_BULK_MAX_MERGE_GROUPS: &str = "memtable.bulk.max_merge_groups";
/// Option key for memtable partition tree index max keys per shard.
pub const MEMTABLE_PARTITION_TREE_INDEX_MAX_KEYS_PER_SHARD: &str =
    "memtable.partition_tree.index_max_keys_per_shard";
/// Option key for memtable partition tree data freeze threshold.
pub const MEMTABLE_PARTITION_TREE_DATA_FREEZE_THRESHOLD: &str =
    "memtable.partition_tree.data_freeze_threshold";
/// Option key for memtable partition tree fork dictionary bytes.
pub const MEMTABLE_PARTITION_TREE_FORK_DICTIONARY_BYTES: &str =
    "memtable.partition_tree.fork_dictionary_bytes";
/// Option key for skipping WAL.
pub const SKIP_WAL_KEY: &str = "skip_wal";
/// Option key for sst format.
pub const SST_FORMAT_KEY: &str = "sst_format";
/// Option key for the max number of rows in a parquet row group.
pub const MAX_ROW_GROUP_ROW_COUNT: &str = "max_row_group_row_count";
/// Upper bound for [`MAX_ROW_GROUP_ROW_COUNT`].
pub const MAX_ROW_GROUP_ROW_COUNT_LIMIT: usize = 10 * 1024 * 1024;
/// Option key for preserving per-row sequence numbers through flush and compaction.
pub const PRESERVE_ROW_SEQUENCE: &str = "preserve_row_sequence";
// Note: Adding new options here should also check if this option should be removed in [metric_engine::engine::create::region_options_for_metadata_region].

/// Returns true if the `key` is a valid option key for the mito engine.
pub fn is_mito_engine_option_key(key: &str) -> bool {
    [
        "ttl",
        WRITE_BUFFER_SIZE_KEY,
        AUTO_FLUSH_INTERVAL_KEY,
        COMPACTION_TYPE,
        COMPACTION_OVERRIDE,
        TWCS_TRIGGER_FILE_NUM,
        TWCS_MAX_OUTPUT_FILE_SIZE,
        TWCS_TIME_WINDOW,
        TWCS_REMOTE_COMPACTION,
        TWCS_FALLBACK_TO_LOCAL,
        "storage",
        "index.inverted_index.ignore_column_ids",
        "index.inverted_index.segment_row_count",
        WAL_OPTIONS_KEY,
        MEMTABLE_TYPE,
        MEMTABLE_BULK_MERGE_THRESHOLD,
        MEMTABLE_BULK_ENCODE_ROW_THRESHOLD,
        MEMTABLE_BULK_ENCODE_BYTES_THRESHOLD,
        MEMTABLE_BULK_MAX_MERGE_GROUPS,
        MEMTABLE_PARTITION_TREE_INDEX_MAX_KEYS_PER_SHARD,
        MEMTABLE_PARTITION_TREE_DATA_FREEZE_THRESHOLD,
        MEMTABLE_PARTITION_TREE_FORK_DICTIONARY_BYTES,
        // We don't allow to create a mito table with sparse primary key encoding directly.
        APPEND_MODE_KEY,
        MERGE_MODE_KEY,
        SST_FORMAT_KEY,
        MAX_ROW_GROUP_ROW_COUNT,
        PRESERVE_ROW_SEQUENCE,
    ]
    .contains(&key)
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_is_mito_engine_option_key() {
        assert!(is_mito_engine_option_key("ttl"));
        assert!(is_mito_engine_option_key("write_buffer_size"));
        assert!(is_mito_engine_option_key("auto_flush_interval"));
        assert!(is_mito_engine_option_key("compaction.type"));
        assert!(is_mito_engine_option_key("compaction.override"));
        assert!(is_mito_engine_option_key(
            "compaction.twcs.trigger_file_num"
        ));
        assert!(is_mito_engine_option_key("compaction.twcs.time_window"));
        assert!(is_mito_engine_option_key("storage"));
        assert!(is_mito_engine_option_key(
            "index.inverted_index.ignore_column_ids"
        ));
        assert!(is_mito_engine_option_key(
            "index.inverted_index.segment_row_count"
        ));
        assert!(is_mito_engine_option_key("wal_options"));
        assert!(is_mito_engine_option_key("memtable.type"));
        assert!(is_mito_engine_option_key("memtable.bulk.merge_threshold"));
        assert!(is_mito_engine_option_key(
            "memtable.bulk.encode_row_threshold"
        ));
        assert!(is_mito_engine_option_key(
            "memtable.bulk.encode_bytes_threshold"
        ));
        assert!(is_mito_engine_option_key("memtable.bulk.max_merge_groups"));
        assert!(is_mito_engine_option_key(
            "memtable.partition_tree.index_max_keys_per_shard"
        ));
        assert!(is_mito_engine_option_key(
            "memtable.partition_tree.data_freeze_threshold"
        ));
        assert!(is_mito_engine_option_key(
            "memtable.partition_tree.fork_dictionary_bytes"
        ));
        assert!(is_mito_engine_option_key("append_mode"));
        assert!(is_mito_engine_option_key("max_row_group_row_count"));
        assert!(is_mito_engine_option_key("preserve_row_sequence"));
        assert!(!is_mito_engine_option_key("foo"));
    }
}
