/*
 * 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 a
 *
 *     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 <gtest/gtest.h>
#include <unistd.h>
#include <utils/db_utils.h>

#include <cstring>
#include <string>

extern "C" {
#include "cwrapper/errno_define_c.h"
#include "cwrapper/tsfile_cwrapper.h"
}

#include "common/tablet.h"
#include "utils/errno_define.h"
namespace CReleaseTest {
class CReleaseTest : public testing::Test {};

TEST_F(CReleaseTest, TestCreateFile) {
    ERRNO error_no = RET_OK;
    // Create File and Get RET_OK
    WriteFile file = write_file_new("create_file1.tsfile", &error_no);
    ASSERT_EQ(RET_OK, error_no);
    free_write_file(&file);

    // Already exists
    file = write_file_new("create_file1.tsfile", &error_no);
    ASSERT_EQ(RET_ALREADY_EXIST, error_no);
    ASSERT_EQ(nullptr, file);

    // Folder
    file = write_file_new("test/", &error_no);
    ASSERT_EQ(RET_FILRET_OPEN_ERR, error_no);

    remove("create_file1.tsfile");
    free_write_file(&file);
}

TEST_F(CReleaseTest, TsFileWriterNew) {
    ERRNO error_code = RET_OK;

    TableSchema test_schema;
    test_schema.table_name = strdup("test_table");
    test_schema.column_num = 0;

    // Invalid schema
    WriteFile file = write_file_new("test_empty_schema.tsfile", &error_code);
    ASSERT_EQ(RET_OK, error_code);
    TsFileWriter writer = tsfile_writer_new(file, &test_schema, &error_code);
    ASSERT_EQ(RET_INVALID_SCHEMA, error_code);
    ASSERT_EQ(nullptr, writer);
    ASSERT_EQ(RET_OK, tsfile_writer_close(writer));
    free_write_file(&file);
    ASSERT_EQ(nullptr, file);
    remove("test_empty_schema.tsfile");

    // Invalid schema with memory threshold
    file = write_file_new("test_empty_schema_memory_threshold.tsfile",
                          &error_code);
    ASSERT_EQ(RET_OK, error_code);
    // Invalid schema
    writer = tsfile_writer_new_with_memory_threshold(file, &test_schema, 100,
                                                     &error_code);
    ASSERT_EQ(RET_INVALID_SCHEMA, error_code);
    ASSERT_EQ(nullptr, writer);
    ASSERT_EQ(RET_OK, tsfile_writer_close(writer));
    free_write_file(&file);
    ASSERT_EQ(nullptr, file);
    remove("test_empty_schema_memory_threshold.tsfile");

    // Normal schema
    file = write_file_new("test_empty_writer.tsfile", &error_code);
    ASSERT_EQ(RET_OK, error_code);

    TableSchema table_schema;
    table_schema.table_name = strdup("test_table");
    table_schema.column_num = 2;
    table_schema.column_schemas =
        static_cast<ColumnSchema*>(malloc(sizeof(ColumnSchema) * 2));
    table_schema.column_schemas[0] =
        (ColumnSchema){.column_name = strdup("col1"),
                       .data_type = TS_DATATYPE_STRING,
                       .column_category = TAG};
    table_schema.column_schemas[1] =
        (ColumnSchema){.column_name = strdup("col2"),
                       .data_type = TS_DATATYPE_INT32,
                       .column_category = FIELD};

    writer = tsfile_writer_new(file, &table_schema, &error_code);
    ASSERT_EQ(RET_OK, error_code);
    error_code = tsfile_writer_close(writer);
    ASSERT_EQ(RET_OK, error_code);
    free_write_file(&file);
    remove("test_empty_writer.tsfile");

    free_table_schema(table_schema);
    free_table_schema(test_schema);
}

TEST_F(CReleaseTest, TsFileWriterWriteDataAbnormalColumn) {
    remove("TsFileWriterWriteDataAbnormalColumn.tsfile");
    ERRNO error_code = RET_OK;
    WriteFile file = write_file_new(
        "TsFileWriterWriteDataAbnormalColumn.tsfile", &error_code);

    TableSchema abnormal_schema;
    abnormal_schema.table_name = strdup("!@#$%^*()_+-=");
    abnormal_schema.column_num = 3;
    abnormal_schema.column_schemas =
        static_cast<ColumnSchema*>(malloc(sizeof(ColumnSchema) * 4));
    abnormal_schema.column_schemas[0] =
        (ColumnSchema){.column_name = strdup("!@#$%^*()_+-="),
                       .data_type = TS_DATATYPE_STRING,
                       .column_category = TAG};

    // TAG's datatype is not correct
    abnormal_schema.column_schemas[1] =
        (ColumnSchema){.column_name = strdup("TAG2"),
                       .data_type = TS_DATATYPE_INT32,
                       .column_category = TAG};

    // same column name with column[0]
    abnormal_schema.column_schemas[2] =
        (ColumnSchema){.column_name = strdup("!@#$%^*()_+-="),
                       .data_type = TS_DATATYPE_DOUBLE,
                       .column_category = FIELD};

    // column name conflict
    TsFileWriter writer =
        tsfile_writer_new(file, &abnormal_schema, &error_code);
    ASSERT_EQ(RET_INVALID_SCHEMA, error_code);
    free(abnormal_schema.column_schemas[2].column_name);

    abnormal_schema.column_schemas[2] =
        (ColumnSchema){.column_name = strdup("!@#$%^*()_+-=1"),
                       .data_type = TS_DATATYPE_DOUBLE,
                       .column_category = FIELD};

    // datatype conflict
    writer = tsfile_writer_new(file, &abnormal_schema, &error_code);
    ASSERT_EQ(RET_INVALID_SCHEMA, error_code);

    free(abnormal_schema.column_schemas[1].column_name);
    abnormal_schema.column_schemas[1] =
        (ColumnSchema){.column_name = strdup("TAG2"),
                       .data_type = TS_DATATYPE_STRING,
                       .column_category = TAG};

    writer = tsfile_writer_new(file, &abnormal_schema, &error_code);
    ASSERT_EQ(RET_OK, error_code);

    char** column_list = static_cast<char**>(malloc(sizeof(char*) * 3));
    column_list[0] = strdup("!@#$%^*()_+-=");
    column_list[1] = strdup("TAG2");
    column_list[2] = strdup("!@#$%^*()_+-=1");
    TSDataType* type_list =
        static_cast<TSDataType*>(malloc(sizeof(TSDataType) * 3));
    type_list[0] = TS_DATATYPE_STRING;
    type_list[1] = TS_DATATYPE_STRING;
    type_list[2] = TS_DATATYPE_DOUBLE;
    Tablet tablet = tablet_new(column_list, type_list, 3, 100);
    for (int i = 0; i < 100; i++) {
        tablet_add_timestamp(tablet, i, static_cast<int64_t>(i));
        tablet_add_value_by_name_string_with_len(
            tablet, i, "!@#$%^*()_+-=", "device1", strlen("device1"));
        tablet_add_value_by_index_string_with_len(
            tablet, i, 1, std::string("sensor" + std::to_string(i)).c_str(),
            std::string("sensor" + std::to_string(i)).length());
        tablet_add_value_by_name_double(tablet, i, "!@#$%^*()_+-=1", i * 100.0);
    }
    ASSERT_EQ(RET_OK, tsfile_writer_write(writer, tablet));
    ASSERT_EQ(RET_OK, tsfile_writer_close(writer));
    free_write_file(&file);

    TsFileReader reader = tsfile_reader_new(
        "TsFileWriterWriteDataAbnormalColumn.tsfile", &error_code);
    ASSERT_EQ(RET_OK, error_code);
    int i = 0;
    ResultSet result_set = tsfile_query_table(
        reader, "!@#$%^*()_+-=", column_list, 3, 0, 100, &error_code);
    while (tsfile_result_set_next(result_set, &error_code) &&
           error_code == RET_OK) {
        Timestamp timestamp =
            tsfile_result_set_get_value_by_name_int64_t(result_set, "time");
        ASSERT_EQ(timestamp * 100.0, tsfile_result_set_get_value_by_name_double(
                                         result_set, "!@#$%^*()_+-=1"));
        char* value_str =
            tsfile_result_set_get_value_by_index_string(result_set, 2);
        ASSERT_EQ("device1", std::string(value_str));
        free(value_str);
        i++;
    }
    ASSERT_EQ(100, i);
    for (int i = 0; i < 3; i++) {
        free(column_list[i]);
    }
    free(column_list);
    free(type_list);
    free_write_file(&file);
    free_table_schema(abnormal_schema);
    free_tablet(&tablet);
    free_tsfile_result_set(&result_set);
    tsfile_reader_close(reader);
    remove("TsFileWriterWriteDataAbnormalColumn.tsfile");
}

TEST_F(CReleaseTest, TsFileWriterMultiDataType) {
    ERRNO error_code = RET_OK;
    remove("TsFileWriterMultiDataType.tsfile");
    WriteFile file =
        write_file_new("TsFileWriterMultiDataType.tsfile", &error_code);
    ASSERT_EQ(RET_OK, error_code);
    TableSchema all_type_schema;
    all_type_schema.table_name = strdup("All_Datatype");
    all_type_schema.column_num = 6;
    all_type_schema.column_schemas =
        static_cast<ColumnSchema*>(malloc(sizeof(ColumnSchema) * 6));
    all_type_schema.column_schemas[0] =
        (ColumnSchema){.column_name = strdup("TAG"),
                       .data_type = TS_DATATYPE_STRING,
                       .column_category = TAG};
    all_type_schema.column_schemas[1] =
        (ColumnSchema){.column_name = strdup("INT32"),
                       .data_type = TS_DATATYPE_INT32,
                       .column_category = FIELD};
    all_type_schema.column_schemas[2] =
        (ColumnSchema){.column_name = strdup("INT64"),
                       .data_type = TS_DATATYPE_INT64,
                       .column_category = FIELD};
    all_type_schema.column_schemas[3] =
        (ColumnSchema){.column_name = strdup("FLOAT"),
                       .data_type = TS_DATATYPE_FLOAT,
                       .column_category = FIELD};
    all_type_schema.column_schemas[4] =
        (ColumnSchema){.column_name = strdup("DOUBLE"),
                       .data_type = TS_DATATYPE_DOUBLE,
                       .column_category = FIELD};
    all_type_schema.column_schemas[5] =
        (ColumnSchema){.column_name = strdup("BOOLEAN"),
                       .data_type = TS_DATATYPE_BOOLEAN,
                       .column_category = FIELD};

    TsFileWriter writer =
        tsfile_writer_new(file, &all_type_schema, &error_code);
    ASSERT_EQ(RET_OK, error_code);

    free_table_schema(all_type_schema);
    char** column_list = static_cast<char**>(malloc(sizeof(char*) * 6));
    column_list[0] = strdup("TAG");
    column_list[1] = strdup("INT32");
    column_list[2] = strdup("INT64");
    column_list[3] = strdup("FLOAT");
    column_list[4] = strdup("DOUBLE");
    column_list[5] = strdup("BOOLEAN");
    TSDataType* type_list =
        static_cast<TSDataType*>(malloc(sizeof(TSDataType) * 6));
    type_list[0] = TS_DATATYPE_STRING;
    type_list[1] = TS_DATATYPE_INT32;
    type_list[2] = TS_DATATYPE_INT64;
    type_list[3] = TS_DATATYPE_FLOAT;
    type_list[4] = TS_DATATYPE_DOUBLE;
    type_list[5] = TS_DATATYPE_BOOLEAN;
    Tablet tablet = tablet_new(column_list, type_list, 6, 1000);
    for (int i = 0; i < 1000; i++) {
        // negative timestamp included
        tablet_add_timestamp(tablet, i, static_cast<int64_t>(i - 10));
        tablet_add_value_by_name_string_with_len(tablet, i, "TAG", "device1",
                                                 strlen("device1"));
        tablet_add_value_by_name_int32_t(tablet, i, "INT32", i);
        tablet_add_value_by_index_int64_t(tablet, i, 2, i * 100);
        tablet_add_value_by_index_float(tablet, i, 3, i * 100.0);
        if (i > 900) {
            continue;
        }
        // Null value
        tablet_add_value_by_index_double(tablet, i, 4, i * 100.0);
        tablet_add_value_by_index_bool(tablet, i, 5, i % 2 == 0);
    }
    ASSERT_EQ(RET_OK, tsfile_writer_write(writer, tablet));
    ASSERT_EQ(RET_OK, tsfile_writer_close(writer));
    free_write_file(&file);

    TsFileReader reader =
        tsfile_reader_new("TsFileWriterMultiDataType.tsfile", &error_code);
    ASSERT_EQ(RET_OK, error_code);
    ResultSet result_set = tsfile_query_table(
        reader, "all_datatype", column_list, 6, 0, 1000, &error_code);
    int row_num = 0;
    while (tsfile_result_set_next(result_set, &error_code) &&
           error_code == RET_OK) {
        Timestamp timestamp =
            tsfile_result_set_get_value_by_name_int64_t(result_set, "time");
        int64_t value = timestamp + 10;
        char* str_value =
            tsfile_result_set_get_value_by_name_string(result_set, "TAG");
        ASSERT_EQ("device1", std::string(str_value));
        free(str_value);
        ASSERT_EQ(value, tsfile_result_set_get_value_by_name_int32_t(result_set,
                                                                     "int32"));
        ASSERT_EQ(value * 100, tsfile_result_set_get_value_by_name_int64_t(
                                   result_set, "int64"));
        ASSERT_EQ(value * 100.0, tsfile_result_set_get_value_by_name_float(
                                     result_set, "FLOAT"));

        if (value <= 900) {
            ASSERT_EQ(value * 100.0, tsfile_result_set_get_value_by_name_double(
                                         result_set, "DOUBLE"));
            ASSERT_EQ(value % 2 == 0, tsfile_result_set_get_value_by_name_bool(
                                          result_set, "BOOLEAN"));
        } else {
            ASSERT_TRUE(
                tsfile_result_set_is_null_by_name(result_set, "DOUBLE"));
        }
        row_num++;
    }
    ASSERT_EQ(990, row_num);
    free_tsfile_result_set(&result_set);
    tsfile_reader_close(reader);
    for (int i = 0; i < 6; i++) {
        free(column_list[i]);
    }
    free_tablet(&tablet);
    free(column_list);
    free(type_list);
    remove("TsFileWriterMultiDataType.tsfile");
}

TEST_F(CReleaseTest, TsFileWriterConfTest) {
    ERRNO err_no = RET_OK;
    WriteFile file = write_file_new("plain_file.tsfile", &err_no);
    TableSchema plain_schema;
    plain_schema.table_name = strdup("plain_table");
    plain_schema.column_num = 2;

    plain_schema.column_schemas =
        (ColumnSchema*)malloc(sizeof(ColumnSchema) * 2);
    plain_schema.column_schemas[0].column_name = strdup("id");
    plain_schema.column_schemas[0].data_type = TS_DATATYPE_STRING;
    plain_schema.column_schemas[0].column_category = ColumnCategory::TAG;
    plain_schema.column_schemas[1].column_name = strdup("value");
    plain_schema.column_schemas[1].data_type = TS_DATATYPE_INT64;
    plain_schema.column_schemas[1].column_category = ColumnCategory::FIELD;

    set_global_compression(TS_COMPRESSION_UNCOMPRESSED);
    set_datatype_encoding(TS_DATATYPE_INT64, TS_ENCODING_PLAIN);
    TsFileWriter writer = tsfile_writer_new(file, &plain_schema, &err_no);
    free_table_schema(plain_schema);

    char** column_list = static_cast<char**>(malloc(sizeof(char*) * 2));
    column_list[0] = strdup("id");
    column_list[1] = strdup("value");

    TSDataType* type_list =
        static_cast<TSDataType*>(malloc(sizeof(TSDataType) * 2));
    type_list[0] = TS_DATATYPE_STRING;
    type_list[1] = TS_DATATYPE_INT64;

    Tablet tablet = tablet_new(column_list, type_list, 2, 10);
    for (int i = 0; i < 10; i++) {
        tablet_add_timestamp(tablet, i, static_cast<int64_t>(i));
        tablet_add_value_by_name_string_with_len(tablet, i, "id", "device1",
                                                 strlen("device1"));
        tablet_add_value_by_name_int32_t(tablet, i, "value", i);
    }

    ASSERT_EQ(RET_OK, tsfile_writer_write(writer, tablet));
    ASSERT_EQ(RET_OK, tsfile_writer_close(writer));
    free_write_file(&file);
    TsFileReader reader = tsfile_reader_new("plain_file.tsfile", &err_no);
    ASSERT_EQ(RET_OK, err_no);
    TableSchema schema = tsfile_reader_get_table_schema(reader, "plain_table");
    ASSERT_EQ(schema.column_num, 2);
    uint32_t size = 0;
    DeviceSchema* device_schema =
        tsfile_reader_get_all_timeseries_schemas(reader, &size);
    ASSERT_EQ(1, size);
    ASSERT_EQ(1, device_schema->timeseries_num);
    ASSERT_EQ(device_schema->timeseries_schema[0].encoding, TS_ENCODING_PLAIN);
    ASSERT_EQ(device_schema->timeseries_schema[0].compression,
              TS_COMPRESSION_UNCOMPRESSED);
    tsfile_reader_close(reader);
    free_table_schema(schema);
    free_device_schema(*device_schema);
    free(device_schema);
    free(column_list[0]);
    free(column_list[1]);
    free(column_list);
    free(type_list);
    free_tablet(&tablet);

    remove("plain_file.tsfile");
}

}  // namespace CReleaseTest