// 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>
#include <testutil/column_helper.h>
#include <vec/columns/column_array.h>
#include <vec/columns/column_const.h>
#include <vec/columns/column_vector.h>
#include <vec/data_types/data_type_array.h>
#include <vec/data_types/data_type_number.h>

#include <cstring>
#include <vector>

#include "common/exception.h"
#include "runtime/primitive_type.h"
#include "vec/columns/column.h"

namespace doris::vectorized {

TEST(ColumnConstTest, TestCreate) {
    auto column_data = ColumnHelper::create_column<DataTypeInt64>({7});
    auto column_const = ColumnConst::create(column_data, 10);
    auto column_const2 = ColumnConst::create(std::move(column_const), 12);
    EXPECT_EQ(column_const2->size(), 12);

    EXPECT_TRUE(!is_column_const(column_const2->get_data_column()));
}

TEST(ColumnConstTest, TestFilter) {
    {
        auto column_data = ColumnHelper::create_column<DataTypeInt64>({7});
        auto column_const = ColumnConst::create(column_data, 3);
        IColumn::Filter filter = {1, 0, 1};

        auto res = column_const->filter(filter, 2);
        EXPECT_EQ(res->size(), 2);
        EXPECT_EQ(assert_cast<const ColumnConst&>(*res).get_data_column_ptr()->size(), 1);
        EXPECT_EQ(assert_cast<const ColumnConst&>(*res).get_data_column_ptr()->get_int(0), 7);
    }

    {
        auto column_data = ColumnHelper::create_column<DataTypeInt64>({7});
        auto column_const = ColumnConst::create(column_data, 3);
        IColumn::Filter filter = {1, 0, 1};

        auto size = column_const->filter(filter);
        EXPECT_EQ(size, 2);
        EXPECT_EQ(assert_cast<const ColumnConst&>(*column_const).get_data_column_ptr()->size(), 1);
        EXPECT_EQ(assert_cast<const ColumnConst&>(*column_const).get_data_column_ptr()->get_int(0),
                  7);
    }
}

TEST(ColumnConstTest, TestPermutation) {
    {
        auto column_data = ColumnHelper::create_column<DataTypeInt64>({7});
        auto column_const = ColumnConst::create(column_data, 3);
        IColumn::Permutation perm = {2, 1, 0};
        auto res = column_const->permute(perm, 3);
        EXPECT_EQ(res->size(), 3);
    }

    {
        auto column_data = ColumnHelper::create_column<DataTypeInt64>({7});
        auto column_const = ColumnConst::create(column_data, 3);
        IColumn::Permutation perm = {2, 1, 0};
        auto res = column_const->permute(perm, 0);
        EXPECT_EQ(res->size(), 3);
    }
}

TEST(ColumnConstTest, Testget_permutation) {
    auto column_data = ColumnHelper::create_column<DataTypeInt64>({7});
    auto column_const = ColumnConst::create(column_data, 3);
    IColumn::Permutation res;
    column_const->get_permutation(false, 0, 0, res);
    EXPECT_EQ(res.size(), 3);
    for (size_t i = 0; i < res.size(); ++i) {
        EXPECT_EQ(res[i], i);
    }
}

TEST(ColumnConstTest, is_variable_length) {
    auto column_data = ColumnHelper::create_column<DataTypeInt64>({7});
    auto column_const = ColumnConst::create(column_data, 3);
    EXPECT_FALSE(column_const->is_variable_length());
}

TEST(ColumnConstTest, get_and_insert) {
    auto column_data = ColumnHelper::create_column<DataTypeInt64>({7});
    auto column_const = ColumnConst::create(column_data, 3);
    EXPECT_EQ(column_const->get_data_column().get_int(0), 7);

    {
        auto dummy_column = ColumnHelper::create_column<DataTypeInt64>({6});
        try {
            column_const->insert_range_from(*dummy_column, 0, 5);
            EXPECT_FALSE(true);
        } catch (const Exception& e) {
            EXPECT_EQ(e.code(), ErrorCode::INTERNAL_ERROR);
        }

        try {
            column_const->insert_many_from(*dummy_column, 0, 5);
            EXPECT_FALSE(true);
        } catch (const Exception& e) {
            EXPECT_EQ(e.code(), ErrorCode::INTERNAL_ERROR);
        }

        try {
            column_const->insert_from(*dummy_column, 0);
            EXPECT_FALSE(true);
        } catch (const Exception& e) {
            EXPECT_EQ(e.code(), ErrorCode::INTERNAL_ERROR);
        }

        try {
            std::vector<uint32_t> indices = {0, 1, 2, 3, 4};
            column_const->insert_indices_from(*dummy_column, indices.data(),
                                              indices.data() + indices.size());
            EXPECT_FALSE(true);
        } catch (const Exception& e) {
            EXPECT_EQ(e.code(), ErrorCode::INTERNAL_ERROR);
        }
    }

    auto dummy_column = ColumnConst::create(column_data, 3);
    column_const->insert_range_from(*dummy_column, 0, 5);
    EXPECT_EQ(column_const->size(), 8);

    column_const->insert_many_from(*dummy_column, 0, 5);
    EXPECT_EQ(column_const->size(), 13);

    std::vector<uint32_t> indices = {0, 1, 2, 3, 4};
    column_const->insert_indices_from(*dummy_column, indices.data(),
                                      indices.data() + indices.size());
    EXPECT_EQ(column_const->size(), 18);

    Field field;
    column_const->insert(field);
    EXPECT_EQ(column_const->size(), 19);

    column_const->insert_data(reinterpret_cast<const char*>(&field), 0);
    EXPECT_EQ(column_const->size(), 20);

    column_const->insert_from(*dummy_column, 0);
    EXPECT_EQ(column_const->size(), 21);

    column_const->insert_default();
    EXPECT_EQ(column_const->size(), 22);

    column_const->pop_back(2);
    EXPECT_EQ(column_const->size(), 20);

    EXPECT_EQ(column_const->get_max_row_byte_size(), 8);
}

TEST(ColumnConstTest, serialize_deserialize) {
    auto column_data = ColumnHelper::create_column<DataTypeInt64>({7});
    auto column_const = ColumnConst::create(column_data, 3);
    Arena arena;
    char const* begin = nullptr;
    StringRef ref = column_const->serialize_value_into_arena(0, arena, begin);
    EXPECT_EQ(ref.size, 8);

    auto new_column_const = ColumnConst::create(column_data, 3);
    const char* pos = new_column_const->deserialize_and_insert_from_arena(ref.data);
    EXPECT_EQ(pos, ref.data + ref.size);
    EXPECT_EQ(new_column_const->size(), 4);
}

TEST(ColumnConstTest, update_xxHash_with_value) {
    {
        auto column_data = ColumnHelper::create_column<DataTypeInt64>({7});
        auto column_const = ColumnConst::create(column_data, 3);
        uint64_t hash = 0;
        column_const->update_xxHash_with_value(0, 1, hash, nullptr);
        std::cout << "hash: " << hash << std::endl;
        EXPECT_EQ(hash, 9324454920402081455ULL);
    }
    {
        auto column_data = ColumnHelper::create_nullable_column<DataTypeInt64>({7}, {true});
        auto column_const = ColumnConst::create(column_data, 3);
        uint64_t hash = 0;
        column_const->update_xxHash_with_value(0, 1, hash, nullptr);
        std::cout << "hash: " << hash << std::endl;
        EXPECT_EQ(hash, 5238470482016868669ULL);
    }

    {
        auto column_data = ColumnHelper::create_column<DataTypeInt64>({7});
        auto column_const = ColumnConst::create(column_data, 3);
        uint32_t hash = 0;
        column_const->update_crc_with_value(0, 1, hash, nullptr);
        std::cout << "hash: " << hash << std::endl;
        EXPECT_EQ(hash, 1877464688U);
    }
    {
        auto column_data = ColumnHelper::create_column<DataTypeInt64>({7});
        auto column_const = ColumnConst::create(column_data, 3);
        SipHash hash;
        column_const->update_hash_with_value(0, hash);
        EXPECT_EQ(hash.get64(), 13180436571133193200ULL);
    }
}

TEST(ColumnConstTest, compare_at) {
    {
        auto column_data = ColumnHelper::create_column<DataTypeInt64>({7});
        auto column_const = ColumnConst::create(column_data, 3);
        EXPECT_EQ(column_const->compare_at(0, 0, *column_const, 1), 0);
        EXPECT_EQ(column_const->compare_at(0, 1, *column_const, 1), 0);
    }

    {
        auto column_data = ColumnHelper::create_column<DataTypeInt64>({7});
        auto column_const = ColumnConst::create(column_data, 3);
        auto column_data2 = ColumnHelper::create_column<DataTypeInt64>({8});
        auto column_const2 = ColumnConst::create(column_data2, 3);
        EXPECT_EQ(column_const->compare_at(0, 0, *column_const2, 1), -1);
    }
}

TEST(ColumnConstTest, structure_equals) {
    {
        auto column_data = ColumnHelper::create_column<DataTypeInt64>({7});
        auto column_const = ColumnConst::create(column_data, 3);
        EXPECT_TRUE(column_const->structure_equals(*column_const));
    }

    {
        auto column_data = ColumnHelper::create_column<DataTypeInt64>({7});
        auto column_const = ColumnConst::create(column_data, 3);
        auto column_data2 = ColumnHelper::create_column<DataTypeInt64>({8});
        auto column_const2 = ColumnConst::create(column_data2, 3);
        EXPECT_TRUE(column_const->structure_equals(*column_const2));
    }

    {
        auto column_data = ColumnHelper::create_column<DataTypeInt64>({7});
        auto column_const = ColumnConst::create(column_data, 3);
        auto column_data2 = ColumnHelper::create_column<DataTypeInt64>({7});
        auto column_const2 = ColumnConst::create(column_data2, 4);
        EXPECT_TRUE(column_const->structure_equals(*column_const2));
    }
}

TEST(ColumnConstTest, erase) {
    auto column_data = ColumnHelper::create_column<DataTypeInt64>({7});
    auto column_const = ColumnConst::create(column_data, 3);
    column_const->erase(0, 1);
    EXPECT_EQ(column_const->size(), 2);
    EXPECT_EQ(column_const->get_data_column().get_int(0), 7);

    column_const->erase(1, 1);
    EXPECT_EQ(column_const->size(), 1);
    EXPECT_EQ(column_const->get_data_column().get_int(0), 7);

    column_const->erase(0, 1);
    EXPECT_EQ(column_const->size(), 0);
}

TEST(ColumnConstTest, replace_column_data) {
    auto column_data = ColumnHelper::create_column<DataTypeInt64>({7});
    auto column_const = ColumnConst::create(column_data, 3);
    auto column_data2 = ColumnHelper::create_column<DataTypeInt64>({8});
    try {
        column_const->replace_column_data(*column_data2, 0, 0);
        EXPECT_FALSE(true);
    } catch (Exception&) {
    }
}
TEST(ColumnConstTest, replace_float_special_values) {
    {
        constexpr double d_negative_0 = -0.0;
        constexpr double d_positive_0 = 0.0;
        auto column_data = ColumnHelper::create_column<DataTypeFloat64>({d_negative_0});
        auto column_const = ColumnConst::create(column_data, 3);
        column_const->replace_float_special_values();
        const auto data_element = column_const->get_data_column().get_data_at(0);
        EXPECT_EQ(std::memcmp(data_element.data, &d_positive_0, 8) == 0, true);
        EXPECT_EQ(column_const->size(), 3);
        column_const->finalize();
    }
    {
        constexpr double d_signal_nan = std::numeric_limits<double>::signaling_NaN();
        constexpr double d_quiet_nan = std::numeric_limits<double>::quiet_NaN();
        auto column_data = ColumnHelper::create_column<DataTypeFloat64>({d_signal_nan});
        auto column_const = ColumnConst::create(column_data, 3);
        column_const->replace_float_special_values();
        const auto data_element = column_const->get_data_column().get_data_at(0);
        EXPECT_EQ(std::memcmp(data_element.data, &d_quiet_nan, 8) == 0, true);
        EXPECT_EQ(column_const->size(), 3);
        column_const->finalize();
    }
}
} // namespace doris::vectorized