/*
 * 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 "paimon/common/utils/rapidjson_util.h"

#include <algorithm>
#include <map>
#include <string>
#include <vector>

#include "gtest/gtest.h"
#include "paimon/testing/utils/testharness.h"
#include "rapidjson/allocators.h"
#include "rapidjson/document.h"
#include "rapidjson/rapidjson.h"

namespace paimon::test {

TEST(RapidJsonUtilTest, TestSerializeAndDeserialize) {
    // serialize
    rapidjson::Document doc;
    doc.SetObject();
    rapidjson::Document::AllocatorType& allocator = doc.GetAllocator();
    // string
    std::string str_value = "John";
    doc.AddMember("name", RapidJsonUtil::SerializeValue(str_value, &allocator).Move(), allocator);
    // int
    int32_t int_value = 30;
    doc.AddMember("age", RapidJsonUtil::SerializeValue(int_value, &allocator).Move(), allocator);
    // vector
    std::vector<int> vector_value = {7, 12};
    doc.AddMember("vector_value", RapidJsonUtil::SerializeValue(vector_value, &allocator).Move(),
                  allocator);
    // map
    std::map<std::string, double> map_value = {{"a", 0.2}, {"b", 1.2}};
    doc.AddMember("map_value", RapidJsonUtil::SerializeValue(map_value, &allocator).Move(),
                  allocator);

    // vector of vector
    std::vector<std::vector<int>> vector_of_vector = {{7, 12}, {27, 45}};
    doc.AddMember("vector_of_vector",
                  RapidJsonUtil::SerializeValue(vector_of_vector, &allocator).Move(), allocator);

    // vector of map
    std::vector<std::map<std::string, double>> vector_of_map = {{{{"a", 0.2}, {"b", 1.2}}},
                                                                {{"c", 2.2}, {"d", 3.2}}};
    doc.AddMember("vector_of_map", RapidJsonUtil::SerializeValue(vector_of_map, &allocator).Move(),
                  allocator);

    // map of vector
    std::map<std::string, std::vector<int>> map_of_vector = {{"aa", {7, 12}}, {"bb", {27, 45}}};
    doc.AddMember("map_of_vector", RapidJsonUtil::SerializeValue(map_of_vector, &allocator).Move(),
                  allocator);

    std::optional<int64_t> null_value;
    doc.AddMember("null_value", RapidJsonUtil::SerializeValue(null_value, &allocator).Move(),
                  allocator);

    std::optional<std::string> optional_value("abcd");
    doc.AddMember("optional_value",
                  RapidJsonUtil::SerializeValue(optional_value, &allocator).Move(), allocator);

    // map with int key (not string key, will convert in util)
    std::map<int32_t, int64_t> map_with_int_key = {{100, 1000}, {200, 2000}};
    doc.AddMember("map_with_int_key",
                  RapidJsonUtil::SerializeValue(map_with_int_key, &allocator).Move(), allocator);

    std::string jsonStr;
    ASSERT_TRUE(RapidJsonUtil::ToJson(doc, &jsonStr));

    // deserialize
    rapidjson::Document doc2;
    ASSERT_TRUE(RapidJsonUtil::FromJson(jsonStr, &doc2));

    ASSERT_EQ(str_value, RapidJsonUtil::DeserializeKeyValue<std::string>(doc2, "name", ""));
    ASSERT_EQ(int_value, RapidJsonUtil::DeserializeKeyValue<int32_t>(doc2, "age", -1));
    ASSERT_EQ(vector_value,
              RapidJsonUtil::DeserializeKeyValue<std::vector<int>>(doc2, "vector_value", {}));

    auto de_map_value =
        RapidJsonUtil::DeserializeKeyValue<std::map<std::string, double>>(doc2, "map_value", {});
    ASSERT_EQ(map_value, de_map_value);

    auto de_vector_of_vector = RapidJsonUtil::DeserializeKeyValue<std::vector<std::vector<int>>>(
        doc2, "vector_of_vector", {});
    ASSERT_EQ(vector_of_vector, de_vector_of_vector);

    auto de_vector_of_map =
        RapidJsonUtil::DeserializeKeyValue<std::vector<std::map<std::string, double>>>(
            doc2, "vector_of_map", {});
    ASSERT_EQ(vector_of_map, de_vector_of_map);

    auto de_map_of_vector =
        RapidJsonUtil::DeserializeKeyValue<std::map<std::string, std::vector<int>>>(
            doc2, "map_of_vector", {});
    ASSERT_EQ(map_of_vector, de_map_of_vector);

    auto de_null_value =
        RapidJsonUtil::DeserializeKeyValue<std::optional<int64_t>>(doc2, "null_value");
    ASSERT_EQ(null_value, de_null_value);

    auto de_null_value_with_default = RapidJsonUtil::DeserializeKeyValue<std::optional<int64_t>>(
        doc2, "null_value", /*default_value=*/std::optional<int64_t>(2333));
    ASSERT_EQ(2333, de_null_value_with_default.value());

    auto de_optional_value =
        RapidJsonUtil::DeserializeKeyValue<std::optional<std::string>>(doc2, "optional_value");
    ASSERT_EQ(optional_value, de_optional_value);

    auto de_map_with_int_key = RapidJsonUtil::DeserializeKeyValue<std::map<int32_t, int64_t>>(
        doc2, "map_with_int_key", {});
    ASSERT_EQ(map_with_int_key, de_map_with_int_key);

    // test non exist key, will use default value
    double non_exist_value = 0.0;
    non_exist_value = RapidJsonUtil::DeserializeKeyValue<double>(doc2, "non_exist_key", 2.333);
    ASSERT_EQ(2.333, non_exist_value);
}

TEST(RapidJsonUtilTest, TestMapJsonString) {
    std::map<std::string, std::string> m1 = {{"key1", "value1"}, {"key2", "value2"}};
    std::string result;
    ASSERT_OK(RapidJsonUtil::ToJsonString(m1, &result));
    ASSERT_EQ(result, "{\"key1\":\"value1\",\"key2\":\"value2\"}");

    std::map<std::string, std::string> m2;
    ASSERT_OK(RapidJsonUtil::FromJsonString(result, &m2));
    ASSERT_EQ(m1, m2);
}

}  // namespace paimon::test
