/*
 * 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_ = GORILLA;
    g_config_value_.double_encoding_type_ = GORILLA;
    // Default compression type is LZ4
#ifdef ENABLE_LZ4
    g_config_value_.default_compression_type_ = LZ4;
#else
    g_config_value_.default_compression_type_ = UNCOMPRESSED;
#endif
    // Enforce aligned page size limits strictly by default.
    g_config_value_.strict_page_size_ = true;
}

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 config_set_strict_page_size(bool strict_page_size) {
    g_config_value_.strict_page_size_ = strict_page_size;
}

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
