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

#include "arrow/api.h"
#include "arrow/array/array_base.h"
#include "arrow/array/array_binary.h"
#include "arrow/ipc/json_simple.h"
#include "gtest/gtest.h"
#include "paimon/common/data/binary_array.h"
#include "paimon/common/data/binary_row.h"
#include "paimon/common/data/binary_string.h"
#include "paimon/common/utils/decimal_utils.h"
#include "paimon/data/decimal.h"
#include "paimon/data/timestamp.h"
#include "paimon/memory/bytes.h"
#include "paimon/memory/memory_pool.h"
#include "paimon/testing/utils/testharness.h"

namespace paimon::test {

// Test case: IsVariantNull should return true for NullType
TEST(DataDefineTest, IsVariantNullReturnsTrueForNull) {
    VariantType null_variant = NullType{};
    ASSERT_TRUE(DataDefine::IsVariantNull(null_variant));
}

// Test case: IsVariantNull should return false for non-NullType variants
TEST(DataDefineTest, IsVariantNullReturnsFalseForNonNullTypes) {
    VariantType non_null_variant = 42;  // Example with int
    ASSERT_FALSE(DataDefine::IsVariantNull(non_null_variant));

    non_null_variant = true;  // Example with bool
    ASSERT_FALSE(DataDefine::IsVariantNull(non_null_variant));
}

// Test case: GetVariantValue should return valid value for matched types
TEST(DataDefineTest, GetVariantValue) {
    {
        VariantType int_variant = 42;  // Variant holding an int
        const auto int_value = DataDefine::GetVariantValue<int32_t>(int_variant);
        ASSERT_EQ(int_value, 42);
    }
    {
        VariantType bool_variant = true;  // Variant holding a bool
        const bool bool_value = DataDefine::GetVariantValue<bool>(bool_variant);
        ASSERT_EQ(bool_value, true);
    }
    {
        auto array = std::dynamic_pointer_cast<arrow::StringArray>(
            arrow::ipc::internal::json::ArrayFromJSON(arrow::utf8(), R"(["abc", "def", "hello"])")
                .ValueOrDie());
        VariantType view_variant = array->GetView(2);  // Variant holding a StringView
        const auto view_value = DataDefine::GetVariantValue<std::string_view>(view_variant);
        ASSERT_EQ(std::string(view_value), "hello");
        ASSERT_EQ(DataDefine::VariantValueToString(view_variant), "hello");
    }
}

// Test case: GetVariantValue should return valid value for matching types
TEST(DataDefineTest, GetVariantValueReturnsPointerForMatchingType) {}

// Test case: VariantValueToString should handle NullType
TEST(DataDefineTest, VariantValueToStringReturnsStringForNullType) {
    VariantType null_variant = NullType{};
    ASSERT_EQ(DataDefine::VariantValueToString(null_variant), "null");
}

// Test case: VariantValueToString should handle bool
TEST(DataDefineTest, VariantValueToStringReturnsStringForBool) {
    VariantType bool_variant = true;
    ASSERT_EQ(DataDefine::VariantValueToString(bool_variant), "true");

    bool_variant = false;
    ASSERT_EQ(DataDefine::VariantValueToString(bool_variant), "false");
}

// Test case: VariantValueToString should handle integer types
TEST(DataDefineTest, VariantValueToStringReturnsStringForInt) {
    VariantType int_variant = 42;
    ASSERT_EQ(DataDefine::VariantValueToString(int_variant), "42");
}

// Test case: VariantValueToString should handle string data (BinaryString)
TEST(DataDefineTest, VariantValueToStringReturnsStringForBinaryString) {
    auto pool = GetDefaultPool();
    auto binary_str = BinaryString::FromString("Hello, world!", pool.get());
    VariantType binary_variant = binary_str;
    ASSERT_EQ(DataDefine::VariantValueToString(binary_variant), "Hello, world!");
}

// Test case: VariantValueToString should handle shared_ptr<Bytes>
TEST(DataDefineTest, VariantValueToStringReturnsStringForSharedPtrBytes) {
    auto pool = GetDefaultPool();
    std::shared_ptr<Bytes> bytes_ptr = Bytes::AllocateBytes("abc", pool.get());
    VariantType bytes_variant = bytes_ptr;
    ASSERT_EQ(DataDefine::VariantValueToString(bytes_variant), "abc");
}

// Test case: VariantValueToString should handle Timestamp
TEST(DataDefineTest, VariantValueToStringReturnsStringForTimestamp) {
    auto timestamp =
        Timestamp(/*millisecond=*/1622520000000l, /*nano_of_millisecond=*/0);  // A timestamp value
    VariantType timestamp_variant = timestamp;
    ASSERT_EQ(DataDefine::VariantValueToString(timestamp_variant), timestamp.ToString());
}

// Test case: VariantValueToString should handle Decimal
TEST(DataDefineTest, VariantValueToStringReturnsStringForDecimal) {
    Decimal decimal(38, 38, DecimalUtils::StrToInt128("12345678998765432145678").value());
    VariantType decimal_variant = decimal;
    ASSERT_EQ(DataDefine::VariantValueToString(decimal_variant), decimal.ToString());
}

// Test case: VariantValueToString should handle shared_ptr<InternalRow> (mocking with a string)
TEST(DataDefineTest, VariantValueToStringReturnsStringForInternalRow) {
    std::shared_ptr<InternalRow> row_ptr = std::make_shared<BinaryRow>(0);
    VariantType row_variant = row_ptr;
    ASSERT_EQ(DataDefine::VariantValueToString(row_variant), "row");
}

// Test case: VariantValueToString should handle shared_ptr<InternalArray> (mocking with a string)
TEST(DataDefineTest, VariantValueToStringReturnsStringForInternalArray) {
    auto pool = GetDefaultPool();
    std::shared_ptr<InternalArray> array_ptr = std::make_shared<BinaryArray>();
    VariantType array_variant = array_ptr;
    ASSERT_EQ(DataDefine::VariantValueToString(array_variant), "array");
}

// Test case: GetStringView should handle all variant types and edge cases
TEST(DataDefineTest, GetStringView) {
    auto pool = GetDefaultPool();

    {
        // from string_view
        std::string original = "hello world";
        VariantType view_variant = std::string_view(original.data(), original.size());
        auto result = DataDefine::GetStringView(view_variant);
        ASSERT_EQ(result, "hello world");
        ASSERT_EQ(result.data(), original.data());
    }
    {
        // from shared_ptr<Bytes>
        std::shared_ptr<Bytes> bytes = Bytes::AllocateBytes("test bytes", pool.get());
        VariantType bytes_variant = bytes;
        auto result = DataDefine::GetStringView(bytes_variant);
        ASSERT_EQ(std::string(result), "test bytes");
        ASSERT_EQ(result.size(), 10);
    }
    {
        // from BinaryString
        auto binary_str = BinaryString::FromString("binary string content", pool.get());
        VariantType binary_variant = binary_str;
        auto result = DataDefine::GetStringView(binary_variant);
        ASSERT_EQ(std::string(result), "binary string content");
    }
    {
        // empty string_view
        VariantType view_variant = std::string_view();
        auto result = DataDefine::GetStringView(view_variant);
        ASSERT_TRUE(result.empty());
        ASSERT_EQ(result.size(), 0);
    }
    {
        // empty Bytes
        std::shared_ptr<Bytes> bytes = Bytes::AllocateBytes("", pool.get());
        VariantType bytes_variant = bytes;
        auto result = DataDefine::GetStringView(bytes_variant);
        ASSERT_TRUE(result.empty());
        ASSERT_EQ(result.size(), 0);
    }
    {
        // empty BinaryString
        VariantType binary_variant = BinaryString::EmptyUtf8();
        auto result = DataDefine::GetStringView(binary_variant);
        ASSERT_TRUE(result.empty());
        ASSERT_EQ(result.size(), 0);
    }
}

TEST(DataDefineTest, VariantValueToLiteral) {
    auto pool = GetDefaultPool();

    {
        // BOOL
        VariantType value = true;
        ASSERT_OK_AND_ASSIGN(auto literal,
                             DataDefine::VariantValueToLiteral(value, arrow::Type::type::BOOL));
        ASSERT_EQ(literal.GetValue<bool>(), true);
    }
    {
        // INT8
        VariantType value = static_cast<char>(42);
        ASSERT_OK_AND_ASSIGN(auto literal,
                             DataDefine::VariantValueToLiteral(value, arrow::Type::type::INT8));
        ASSERT_EQ(literal.GetValue<int8_t>(), 42);
    }
    {
        // INT16
        VariantType value = static_cast<int16_t>(1000);
        ASSERT_OK_AND_ASSIGN(auto literal,
                             DataDefine::VariantValueToLiteral(value, arrow::Type::type::INT16));
        ASSERT_EQ(literal.GetValue<int16_t>(), 1000);
    }
    {
        // INT32
        VariantType value = static_cast<int32_t>(100000);
        ASSERT_OK_AND_ASSIGN(auto literal,
                             DataDefine::VariantValueToLiteral(value, arrow::Type::type::INT32));
        ASSERT_EQ(literal.GetValue<int32_t>(), 100000);
    }
    {
        // INT64
        VariantType value = static_cast<int64_t>(123456789L);
        ASSERT_OK_AND_ASSIGN(auto literal,
                             DataDefine::VariantValueToLiteral(value, arrow::Type::type::INT64));
        ASSERT_EQ(literal.GetValue<int64_t>(), 123456789L);
    }
    {
        // FLOAT
        VariantType value = 3.14f;
        ASSERT_OK_AND_ASSIGN(auto literal,
                             DataDefine::VariantValueToLiteral(value, arrow::Type::type::FLOAT));
        ASSERT_FLOAT_EQ(literal.GetValue<float>(), 3.14f);
    }
    {
        // DOUBLE
        VariantType value = 2.718;
        ASSERT_OK_AND_ASSIGN(auto literal,
                             DataDefine::VariantValueToLiteral(value, arrow::Type::type::DOUBLE));
        ASSERT_DOUBLE_EQ(literal.GetValue<double>(), 2.718);
    }
    {
        // STRING from BinaryString
        auto binary_str = BinaryString::FromString("hello", pool.get());
        VariantType value = binary_str;
        ASSERT_OK_AND_ASSIGN(auto literal,
                             DataDefine::VariantValueToLiteral(value, arrow::Type::type::STRING));
        ASSERT_EQ(literal.GetValue<std::string>(), "hello");
    }
    {
        // STRING from shared_ptr<Bytes>
        std::shared_ptr<Bytes> bytes = Bytes::AllocateBytes("world", pool.get());
        VariantType value = bytes;
        ASSERT_OK_AND_ASSIGN(auto literal,
                             DataDefine::VariantValueToLiteral(value, arrow::Type::type::STRING));
        ASSERT_EQ(literal.GetValue<std::string>(), "world");
    }
    {
        // STRING from string_view
        std::string original = "view_str";
        VariantType value = std::string_view(original.data(), original.size());
        ASSERT_OK_AND_ASSIGN(auto literal,
                             DataDefine::VariantValueToLiteral(value, arrow::Type::type::STRING));
        ASSERT_EQ(literal.GetValue<std::string>(), "view_str");
    }
    {
        // BINARY from shared_ptr<Bytes>
        std::shared_ptr<Bytes> bytes = Bytes::AllocateBytes("binary_data", pool.get());
        VariantType value = bytes;
        ASSERT_OK_AND_ASSIGN(auto literal,
                             DataDefine::VariantValueToLiteral(value, arrow::Type::type::BINARY));
        ASSERT_EQ(literal.GetValue<std::string>(), "binary_data");
    }
    {
        // BINARY from BinaryString
        auto binary_str = BinaryString::FromString("bin_str", pool.get());
        VariantType value = binary_str;
        ASSERT_OK_AND_ASSIGN(auto literal,
                             DataDefine::VariantValueToLiteral(value, arrow::Type::type::BINARY));
        ASSERT_EQ(literal.GetValue<std::string>(), "bin_str");
    }
    {
        // TIMESTAMP
        Timestamp ts(12345, 1);
        VariantType value = ts;
        ASSERT_OK_AND_ASSIGN(
            auto literal, DataDefine::VariantValueToLiteral(value, arrow::Type::type::TIMESTAMP));
        ASSERT_EQ(literal.GetValue<Timestamp>(), ts);
    }
    {
        // DECIMAL128
        Decimal decimal(20, 3, 123456);
        VariantType value = decimal;
        ASSERT_OK_AND_ASSIGN(
            auto literal, DataDefine::VariantValueToLiteral(value, arrow::Type::type::DECIMAL128));
        ASSERT_EQ(literal.GetValue<Decimal>(), decimal);
    }
    {
        // DATE32
        VariantType value = static_cast<int32_t>(19000);
        ASSERT_OK_AND_ASSIGN(auto literal,
                             DataDefine::VariantValueToLiteral(value, arrow::Type::type::DATE32));
        ASSERT_EQ(literal.GetValue<int32_t>(), 19000);
    }
    {
        // unsupported type
        VariantType value = static_cast<int32_t>(0);
        ASSERT_NOK_WITH_MSG(DataDefine::VariantValueToLiteral(value, arrow::Type::type::LIST),
                            "Not support arrow type");
    }
}

}  // namespace paimon::test
