/*
 * 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 <gtest/gtest.h>
#ifdef _WIN32
#include <io.h>
#else
#include <unistd.h>
#endif

#include <cstring>
#include <string>

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

namespace cwrapper_metadata {

class CWrapperMetadataTest : public testing::Test {};

TEST_F(CWrapperMetadataTest, GetAllDevicesAndMetadataWithStatistic) {
    ERRNO code = RET_OK;
    const char* filename = "cwrapper_metadata_stat.tsfile";
    remove(filename);

    const char* device = "root.sg.d1";
    char* m_int = strdup("s_int");
    timeseries_schema sch{};
    sch.timeseries_name = m_int;
    sch.data_type = TS_DATATYPE_INT32;
    sch.encoding = TS_ENCODING_PLAIN;
    sch.compression = TS_COMPRESSION_UNCOMPRESSED;

    auto* writer = static_cast<void*>(
        _tsfile_writer_new(filename, 128 * 1024 * 1024, &code));
    ASSERT_EQ(RET_OK, code);
    ASSERT_EQ(RET_OK, _tsfile_writer_register_timeseries(writer, device, &sch));

    for (int row = 0; row < 3; row++) {
        auto* record = static_cast<TsRecord>(
            _ts_record_new(device, static_cast<int64_t>(row + 1), 1));
        const int32_t v = static_cast<int32_t>((row + 1) * 10);
        ASSERT_EQ(RET_OK, _insert_data_into_ts_record_by_name_int32_t(
                              record, m_int, v));
        ASSERT_EQ(RET_OK, _tsfile_writer_write_ts_record(writer, record));
        _free_tsfile_ts_record(reinterpret_cast<TsRecord*>(&record));
    }
    ASSERT_EQ(RET_OK, _tsfile_writer_close(writer));

    TsFileReader reader = tsfile_reader_new(filename, &code);
    ASSERT_EQ(RET_OK, code);
    ASSERT_NE(nullptr, reader);

    DeviceID* details = nullptr;
    uint32_t n_det = 0;
    ASSERT_EQ(RET_OK, tsfile_reader_get_all_devices(reader, &details, &n_det));
    ASSERT_EQ(1u, n_det);
    ASSERT_NE(nullptr, details);
    ASSERT_STREQ(device, details[0].path);
    ASSERT_NE(nullptr, details[0].table_name);
    EXPECT_STREQ("root.sg", details[0].table_name);
    EXPECT_EQ(2u, details[0].segment_count);
    ASSERT_NE(nullptr, details[0].segments);
    EXPECT_STREQ("root.sg", details[0].segments[0]);
    EXPECT_STREQ("d1", details[0].segments[1]);
    tsfile_free_device_id_array(details, n_det);

    DeviceTimeseriesMetadataMap map{};
    ASSERT_EQ(RET_OK, tsfile_reader_get_timeseries_metadata_all(reader, &map));
    ASSERT_EQ(1u, map.device_count);
    ASSERT_NE(nullptr, map.entries);
    ASSERT_STREQ(device, map.entries[0].device.path);
    ASSERT_NE(nullptr, map.entries[0].device.table_name);
    EXPECT_STREQ("root.sg", map.entries[0].device.table_name);
    EXPECT_EQ(2u, map.entries[0].device.segment_count);
    ASSERT_NE(nullptr, map.entries[0].device.segments);
    EXPECT_STREQ("root.sg", map.entries[0].device.segments[0]);
    EXPECT_STREQ("d1", map.entries[0].device.segments[1]);
    ASSERT_EQ(1u, map.entries[0].timeseries_count);
    ASSERT_NE(nullptr, map.entries[0].timeseries);
    TimeseriesMetadata& tm = map.entries[0].timeseries[0];
    ASSERT_STREQ(m_int, tm.measurement_name);
    ASSERT_EQ(TS_DATATYPE_INT32, tm.data_type);
    TsFileStatisticBase* sb = tsfile_statistic_base(&tm.statistic);
    ASSERT_TRUE(sb->has_statistic);
    EXPECT_EQ(3, sb->row_count);
    EXPECT_EQ(1, sb->start_time);
    EXPECT_EQ(3, sb->end_time);
    EXPECT_DOUBLE_EQ(60.0, tm.statistic.u.int_s.sum);
    ASSERT_EQ(TS_DATATYPE_INT32, sb->type);
    EXPECT_EQ(10, tm.statistic.u.int_s.min_int64);
    EXPECT_EQ(30, tm.statistic.u.int_s.max_int64);
    EXPECT_EQ(10, tm.statistic.u.int_s.first_int64);
    EXPECT_EQ(30, tm.statistic.u.int_s.last_int64);

    tsfile_free_device_timeseries_metadata_map(&map);

    DeviceTimeseriesMetadataMap empty{};
    ASSERT_EQ(RET_OK, tsfile_reader_get_timeseries_metadata_for_devices(
                          reader, nullptr, 0, &empty));
    EXPECT_EQ(0u, empty.device_count);
    EXPECT_EQ(nullptr, empty.entries);

    DeviceID q{};
    q.path = const_cast<char*>(device);
    q.table_name = nullptr;
    q.segment_count = 0;
    q.segments = nullptr;
    DeviceTimeseriesMetadataMap one{};
    ASSERT_EQ(RET_OK, tsfile_reader_get_timeseries_metadata_for_devices(
                          reader, &q, 1, &one));
    ASSERT_EQ(1u, one.device_count);
    tsfile_free_device_timeseries_metadata_map(&one);

    ASSERT_EQ(RET_OK, tsfile_reader_close(reader));
    free(m_int);
    remove(filename);
}

TEST_F(CWrapperMetadataTest, GetTimeseriesMetadataBooleanStatistic) {
    ERRNO code = RET_OK;
    const char* filename = "cwrapper_metadata_bool.tsfile";
    remove(filename);

    const char* device = "root.sg.bool";
    char* m_b = strdup("s_bool");
    timeseries_schema sch{};
    sch.timeseries_name = m_b;
    sch.data_type = TS_DATATYPE_BOOLEAN;
    sch.encoding = TS_ENCODING_PLAIN;
    sch.compression = TS_COMPRESSION_UNCOMPRESSED;

    auto* writer = static_cast<void*>(
        _tsfile_writer_new(filename, 128 * 1024 * 1024, &code));
    ASSERT_EQ(RET_OK, code);
    ASSERT_EQ(RET_OK, _tsfile_writer_register_timeseries(writer, device, &sch));

    const bool vals[] = {true, false, true};
    for (int row = 0; row < 3; row++) {
        auto* record = static_cast<TsRecord>(
            _ts_record_new(device, static_cast<int64_t>(row + 1), 1));
        ASSERT_EQ(RET_OK, _insert_data_into_ts_record_by_name_bool(record, m_b,
                                                                   vals[row]));
        ASSERT_EQ(RET_OK, _tsfile_writer_write_ts_record(writer, record));
        _free_tsfile_ts_record(reinterpret_cast<TsRecord*>(&record));
    }
    ASSERT_EQ(RET_OK, _tsfile_writer_close(writer));

    TsFileReader reader = tsfile_reader_new(filename, &code);
    ASSERT_EQ(RET_OK, code);

    DeviceTimeseriesMetadataMap map{};
    ASSERT_EQ(RET_OK, tsfile_reader_get_timeseries_metadata_all(reader, &map));
    TimeseriesMetadata& tm = map.entries[0].timeseries[0];
    ASSERT_STREQ(m_b, tm.measurement_name);
    ASSERT_EQ(TS_DATATYPE_BOOLEAN, tm.data_type);
    TsFileStatisticBase* sb = tsfile_statistic_base(&tm.statistic);
    ASSERT_TRUE(sb->has_statistic);
    EXPECT_DOUBLE_EQ(2.0, tm.statistic.u.bool_s.sum);
    ASSERT_EQ(TS_DATATYPE_BOOLEAN, sb->type);
    EXPECT_TRUE(tm.statistic.u.bool_s.first_bool);
    EXPECT_TRUE(tm.statistic.u.bool_s.last_bool);

    tsfile_free_device_timeseries_metadata_map(&map);
    ASSERT_EQ(RET_OK, tsfile_reader_close(reader));
    free(m_b);
    remove(filename);
}

TEST_F(CWrapperMetadataTest, GetTimeseriesMetadataStringStatistic) {
    ERRNO code = RET_OK;
    const char* filename = "cwrapper_metadata_str.tsfile";
    remove(filename);

    const char* device = "root.sg.str";
    char* m_str = strdup("s_str");
    timeseries_schema sch{};
    sch.timeseries_name = m_str;
    sch.data_type = TS_DATATYPE_STRING;
    sch.encoding = TS_ENCODING_PLAIN;
    sch.compression = TS_COMPRESSION_UNCOMPRESSED;

    auto* writer = static_cast<void*>(
        _tsfile_writer_new(filename, 128 * 1024 * 1024, &code));
    ASSERT_EQ(RET_OK, code);
    ASSERT_EQ(RET_OK, _tsfile_writer_register_timeseries(writer, device, &sch));

    const char* vals[] = {"aa", "cc", "bb"};
    for (int row = 0; row < 3; row++) {
        auto* record = static_cast<TsRecord>(
            _ts_record_new(device, static_cast<int64_t>(row + 1), 1));
        ASSERT_EQ(RET_OK, _insert_data_into_ts_record_by_name_string_with_len(
                              record, m_str, vals[row],
                              static_cast<int>(std::strlen(vals[row]))));
        ASSERT_EQ(RET_OK, _tsfile_writer_write_ts_record(writer, record));
        _free_tsfile_ts_record(reinterpret_cast<TsRecord*>(&record));
    }
    ASSERT_EQ(RET_OK, _tsfile_writer_close(writer));

    TsFileReader reader = tsfile_reader_new(filename, &code);
    ASSERT_EQ(RET_OK, code);

    DeviceTimeseriesMetadataMap map{};
    ASSERT_EQ(RET_OK, tsfile_reader_get_timeseries_metadata_all(reader, &map));
    ASSERT_EQ(1u, map.device_count);
    TimeseriesMetadata& tm = map.entries[0].timeseries[0];
    ASSERT_STREQ(m_str, tm.measurement_name);
    ASSERT_EQ(TS_DATATYPE_STRING, tm.data_type);
    TsFileStatisticBase* sb = tsfile_statistic_base(&tm.statistic);
    ASSERT_TRUE(sb->has_statistic);
    ASSERT_EQ(TS_DATATYPE_STRING, sb->type);
    ASSERT_NE(nullptr, tm.statistic.u.string_s.str_min);
    ASSERT_NE(nullptr, tm.statistic.u.string_s.str_max);
    ASSERT_NE(nullptr, tm.statistic.u.string_s.str_first);
    ASSERT_NE(nullptr, tm.statistic.u.string_s.str_last);
    EXPECT_STREQ("aa", tm.statistic.u.string_s.str_min);
    EXPECT_STREQ("cc", tm.statistic.u.string_s.str_max);
    EXPECT_STREQ("aa", tm.statistic.u.string_s.str_first);
    EXPECT_STREQ("bb", tm.statistic.u.string_s.str_last);

    tsfile_free_device_timeseries_metadata_map(&map);
    ASSERT_EQ(RET_OK, tsfile_reader_close(reader));
    free(m_str);
    remove(filename);
}

TEST_F(CWrapperMetadataTest, GetTimeseriesMetadataNullDevicePath) {
    ERRNO code = RET_OK;
    const char* filename = "cwrapper_metadata_null_path.tsfile";
    remove(filename);

    auto* writer = static_cast<void*>(
        _tsfile_writer_new(filename, 128 * 1024 * 1024, &code));
    ASSERT_EQ(RET_OK, code);
    ASSERT_EQ(RET_OK, _tsfile_writer_close(writer));

    TsFileReader reader = tsfile_reader_new(filename, &code);
    ASSERT_EQ(RET_OK, code);

    DeviceID bad{};
    bad.path = nullptr;
    bad.table_name = nullptr;
    bad.segment_count = 0;
    bad.segments = nullptr;
    DeviceTimeseriesMetadataMap map{};
    EXPECT_EQ(RET_INVALID_ARG,
              tsfile_reader_get_timeseries_metadata_for_devices(reader, &bad, 1,
                                                                &map));

    ASSERT_EQ(RET_OK, tsfile_reader_close(reader));
    remove(filename);
}

TEST_F(CWrapperMetadataTest, GetTimeseriesMetadataInvalidArgs) {
    ERRNO code = RET_OK;
    const char* filename = "cwrapper_metadata_empty.tsfile";
    remove(filename);

    auto* writer = static_cast<void*>(
        _tsfile_writer_new(filename, 128 * 1024 * 1024, &code));
    ASSERT_EQ(RET_OK, code);
    ASSERT_EQ(RET_OK, _tsfile_writer_close(writer));

    TsFileReader reader = tsfile_reader_new(filename, &code);
    ASSERT_EQ(RET_OK, code);

    DeviceTimeseriesMetadataMap map{};
    EXPECT_NE(RET_OK, tsfile_reader_get_timeseries_metadata_all(nullptr, &map));
    EXPECT_NE(RET_OK,
              tsfile_reader_get_timeseries_metadata_all(reader, nullptr));

    ASSERT_EQ(RET_OK, tsfile_reader_close(reader));
    remove(filename);
}

}  // namespace cwrapper_metadata
