/*
 * 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 "global.h"

#ifndef _WIN32
#include <execinfo.h>
#endif
#include <stdlib.h>

#include "utils/injection.h"

namespace common {

ColumnSchema g_time_column_schema;
ConfigValue g_config_value_;

void init_config_value() {
    g_config_value_.tsblock_mem_inc_step_size_ = 8000;  // 8k
    g_config_value_.tsblock_max_memory_ = 64000;        // 64k
    // g_config_value_.tsblock_max_memory_ = 32;
    g_config_value_.page_writer_max_point_num_ = 10000;
    g_config_value_.page_writer_max_memory_bytes_ = 128 * 1024;  // 128 k
    g_config_value_.max_degree_of_index_node_ = 256;
    g_config_value_.tsfile_index_bloom_filter_error_percent_ = 0.05;
    g_config_value_.record_count_for_next_mem_check_ = 100;
    g_config_value_.chunk_group_size_threshold_ = 128 * 1024 * 1024;
    g_config_value_.time_encoding_type_ = TS_2DIFF;
    g_config_value_.time_data_type_ = INT64;
#ifdef ENABLE_LZ4
    g_config_value_.time_compress_type_ = LZ4;
#else
    g_config_value_.time_compress_type_ = UNCOMPRESSED;
#endif
    // Not support RLE yet.
    g_config_value_.boolean_encoding_type_ = PLAIN;
    g_config_value_.int32_encoding_type_ = TS_2DIFF;
    g_config_value_.int64_encoding_type_ = TS_2DIFF;
    g_config_value_.float_encoding_type_ = PLAIN;
    g_config_value_.double_encoding_type_ = PLAIN;
    g_config_value_.string_encoding_type_ = PLAIN;
    // Default compression type is LZ4
#ifdef ENABLE_LZ4
    g_config_value_.default_compression_type_ = SNAPPY;
#else
    g_config_value_.default_compression_type_ = UNCOMPRESSED;
#endif
    g_config_value_.parallel_read_enabled_ = true;
    g_config_value_.parallel_write_enabled_ = true;
    g_config_value_.read_thread_count_ = 4;
    g_config_value_.write_thread_count_ = 6;
}

extern TSEncoding get_value_encoder(TSDataType data_type) {
    switch (data_type) {
        case BOOLEAN:
            return g_config_value_.boolean_encoding_type_;
        case INT32:
        case DATE:
            return g_config_value_.int32_encoding_type_;
        case INT64:
        case TIMESTAMP:
            return g_config_value_.int64_encoding_type_;
        case FLOAT:
            return g_config_value_.float_encoding_type_;
        case DOUBLE:
            return g_config_value_.double_encoding_type_;
        case TEXT:
        case STRING:
        case BLOB:
            return g_config_value_.string_encoding_type_;
        case VECTOR:
            break;
        case NULL_TYPE:
            break;
        case INVALID_DATATYPE:
            break;
        default:
            break;
    }
    return TSEncoding::INVALID_ENCODING;
}

extern CompressionType get_default_compressor() {
    return g_config_value_.default_compression_type_;
}

void config_set_page_max_point_count(uint32_t page_max_point_count) {
    g_config_value_.page_writer_max_point_num_ = page_max_point_count;
}

void config_set_max_degree_of_index_node(uint32_t max_degree_of_index_node) {
    g_config_value_.max_degree_of_index_node_ = max_degree_of_index_node;
}

void set_config_value() {}
const char* s_data_type_names[8] = {"BOOLEAN", "INT32", "INT64",  "FLOAT",
                                    "DOUBLE",  "TEXT",  "VECTOR", "STRING"};

const char* s_encoding_names[12] = {
    "PLAIN",      "DICTIONARY", "RLE",     "DIFF",   "TS_2DIFF", "BITMAP",
    "GORILLA_V1", "REGULAR",    "GORILLA", "ZIGZAG", "FREQ",     "SPRINTZ"};

const char* s_compression_names[8] = {
    "UNCOMPRESSED", "SNAPPY", "GZIP", "LZO", "SDT", "PAA", "PLA", "LZ4",
};

int init_common() {
    int ret = E_OK;
    common::init_config_value();
    g_time_column_schema.data_type_ = INT64;
    g_time_column_schema.encoding_ = PLAIN;
    g_time_column_schema.compression_ = UNCOMPRESSED;
    g_time_column_schema.column_name_ = storage::TIME_COLUMN_NAME;
    return ret;
}

bool is_timestamp_column_name(const char* time_col_name) {
    // both "time" and "timestamp" refer to timestmap column.
    int32_t len = strlen(time_col_name);
    if (len == 4) {
        return strncasecmp(time_col_name, "time", 4) == 0;
    } else if (len == 9) {
        return strncasecmp(time_col_name, "timestamp", 9) == 0;
    } else {
        return false;
    }
}

void cols_to_json(ByteStream* byte_stream,
                  std::vector<common::ColumnSchema>& ret_ts_list) {
    // 1. append start tag
    byte_stream->write_buf("{\n", 2);

    size_t ts_count = ret_ts_list.size();
    for (size_t i = 0; i < ts_count; ++i) {
        // 2. append timeseries name
        std::string name = ret_ts_list[i].column_name_;
        byte_stream->write_buf("  \"", 3);
        byte_stream->write_buf(name.c_str(), name.length());
        byte_stream->write_buf("\" : {\n", 6);

        // 3. append DataType
        const char* data_type = get_data_type_name(ret_ts_list[i].data_type_);
        byte_stream->write_buf("    \"DataType\" : \"", 18);
        byte_stream->write_buf(data_type, strlen(data_type));
        byte_stream->write_buf("\",\n", 3);

        // 4. append Encoding
        const char* encoding = get_encoding_name(ret_ts_list[i].encoding_);
        byte_stream->write_buf("    \"Encoding\" : \"", 18);
        byte_stream->write_buf(encoding, strlen(encoding));
        byte_stream->write_buf("\",\n", 3);

        // 5. append CompressionType
        const char* compression =
            get_compression_name(ret_ts_list[i].compression_);
        byte_stream->write_buf("    \"Compression\" : \"", 21);
        byte_stream->write_buf(compression, strlen(compression));
        byte_stream->write_buf("\",\n", 3);

        // 6. append footer
        if (i == ts_count - 1) {
            byte_stream->write_buf("  }\n", 4);
        } else {
            byte_stream->write_buf("  },\n", 5);
        }
    }

    // 7. end
    byte_stream->write_buf("}\n", 2);

    // DEBUG_print_byte_stream(*byte_stream);  // for debug
}

#ifndef _WIN32
void print_backtrace() {
    const int MAX_FRAMES = 32;
    int layers = 0;
    char** symbols = NULL;
    void* frames[MAX_FRAMES];

    memset(frames, 0, sizeof(frames));
    layers = backtrace(frames, MAX_FRAMES);
    symbols = backtrace_symbols(frames, layers);
    if (symbols) {
        for (int i = 0; i < layers; i++) {
            printf("SYMBOL layer %d: %s\n", i, symbols[i]);
        }
        free(symbols);
    }
}
#endif

std::map<std::string, InjectPoint> g_all_inject_points;

}  // namespace common
