#include <systemd/sd-bus-protocol.h>

#include <sdbusplus/message.hpp>
#include <sdbusplus/test/sdbus_mock.hpp>

#include <array>
#include <map>
#include <set>
#include <span>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <variant>
#include <vector>

#include <gmock/gmock.h>
#include <gtest/gtest.h>

namespace
{

using testing::Eq;
using testing::MatcherCast;
using testing::Pointee;
using testing::Return;
using testing::SafeMatcherCast;
using testing::StrEq;

MATCHER_P(iovec_equal, match_string, "")
{
    const char* start = std::bit_cast<char*>(arg->iov_base);
    return std::string(start, arg->iov_len) == match_string;
}

class AppendTest : public testing::Test
{
  protected:
    testing::StrictMock<sdbusplus::SdBusMock> mock;

    void SetUp() override
    {
        EXPECT_CALL(mock, sd_bus_message_new_method_call(testing::_, testing::_,
                                                         nullptr, nullptr,
                                                         nullptr, nullptr))
            .WillRepeatedly(Return(0));
    };

    sdbusplus::message_t new_message()
    {
        return sdbusplus::get_mocked_new(&mock).new_method_call(
            nullptr, nullptr, nullptr, nullptr);
    }

    template <typename T>
    void expect_basic(char type, T val)
    {
        EXPECT_CALL(mock, sd_bus_message_append_basic(
                              nullptr, type,
                              MatcherCast<const void*>(
                                  SafeMatcherCast<const T*>(Pointee(Eq(val))))))
            .WillOnce(Return(0));
    }

    void expect_basic_string(char type, const char* str)
    {
        EXPECT_CALL(mock, sd_bus_message_append_basic(
                              nullptr, type,
                              MatcherCast<const void*>(
                                  SafeMatcherCast<const char*>(StrEq(str)))))
            .WillOnce(Return(0));
    }
    void expect_basic_string_iovec(const char* str, size_t size)
    {
        std::string tmp = {str, size};
        EXPECT_CALL(mock, sd_bus_message_append_string_iovec(
                              nullptr, iovec_equal(tmp), 1))
            .WillOnce(Return(0));
    }

    void expect_open_container(char type, const char* contents)
    {
        EXPECT_CALL(
            mock, sd_bus_message_open_container(nullptr, type, StrEq(contents)))
            .WillOnce(Return(0));
    }

    void expect_close_container()
    {
        EXPECT_CALL(mock, sd_bus_message_close_container(nullptr))
            .WillOnce(Return(0));
    }
};

TEST_F(AppendTest, RValueInt)
{
    static_assert(
        sdbusplus::message::details::can_append_multiple_v<decltype(1)>);
    expect_basic<int>(SD_BUS_TYPE_INT32, 1);
    new_message().append(1);
}

TEST_F(AppendTest, LValueInt)
{
    const int a = 1;
    static_assert(
        sdbusplus::message::details::can_append_multiple_v<decltype(a)>);
    expect_basic<int>(SD_BUS_TYPE_INT32, a);
    new_message().append(a);
}

TEST_F(AppendTest, XValueInt)
{
    int a = 1;
    expect_basic<int>(SD_BUS_TYPE_INT32, a);
    new_message().append(std::move(a));
}

TEST_F(AppendTest, RValueBool)
{
    expect_basic<int>(SD_BUS_TYPE_BOOLEAN, true);
    new_message().append(true);
}

TEST_F(AppendTest, LValueBool)
{
    const bool a = false;
    expect_basic<int>(SD_BUS_TYPE_BOOLEAN, false);
    new_message().append(a);
}

TEST_F(AppendTest, XValueBool)
{
    bool a = false;
    expect_basic<int>(SD_BUS_TYPE_BOOLEAN, false);
    new_message().append(std::move(a));
}

TEST_F(AppendTest, RValueDouble)
{
    expect_basic<double>(SD_BUS_TYPE_DOUBLE, 1.1);
    new_message().append(1.1);
}

TEST_F(AppendTest, LValueDouble)
{
    const double a = 1.1;
    expect_basic<double>(SD_BUS_TYPE_DOUBLE, a);
    new_message().append(a);
}

TEST_F(AppendTest, XValueDouble)
{
    double a = 1.1;
    expect_basic<double>(SD_BUS_TYPE_DOUBLE, a);
    new_message().append(std::move(a));
}

TEST_F(AppendTest, RValueCString)
{
    expect_basic_string(SD_BUS_TYPE_STRING, "asdf");
    new_message().append("asdf");
}

TEST_F(AppendTest, LValueCString)
{
    const char* const s = "asdf";
    expect_basic_string(SD_BUS_TYPE_STRING, s);
    new_message().append(s);
}

TEST_F(AppendTest, XValueCString)
{
    const char* s = "asdf";
    static_assert(
        sdbusplus::message::details::can_append_multiple_v<decltype(s)>);
    expect_basic_string(SD_BUS_TYPE_STRING, s);
    new_message().append(std::move(s));
}

TEST_F(AppendTest, RValueString)
{
    expect_basic_string(SD_BUS_TYPE_STRING, "asdf");
    new_message().append(std::string{"asdf"});
}

TEST_F(AppendTest, LValueString)
{
    std::string s{"asdf"};
    static_assert(
        !sdbusplus::message::details::can_append_multiple_v<decltype(s)>);
    expect_basic_string(SD_BUS_TYPE_STRING, s.c_str());
    new_message().append(s);
}

TEST_F(AppendTest, XValueString)
{
    std::string s{"asdf"};
    expect_basic_string(SD_BUS_TYPE_STRING, s.c_str());
    new_message().append(std::move(s));
}

TEST_F(AppendTest, LValueStringView)
{
    std::string_view s{"asdf"};
    expect_basic_string_iovec(s.data(), s.size());
    new_message().append(s);
}

TEST_F(AppendTest, RValueStringView)
{
    std::string_view s{"asdf"};
    expect_basic_string_iovec(s.data(), s.size());
    new_message().append(std::string_view{"asdf"});
}

TEST_F(AppendTest, ObjectPath)
{
    sdbusplus::message::object_path o{"/asdf"};
    expect_basic_string(SD_BUS_TYPE_OBJECT_PATH, o.str.c_str());
    new_message().append(o);
}

TEST_F(AppendTest, Signature)
{
    sdbusplus::message::signature g{"ii"};
    expect_basic_string(SD_BUS_TYPE_SIGNATURE, g.str.c_str());
    new_message().append(g);
}

TEST_F(AppendTest, CombinedBasic)
{
    const int c = 3;
    const std::string s1{"fdsa"};
    const char* const s2 = "asdf";

    {
        testing::InSequence seq;
        expect_basic<int>(SD_BUS_TYPE_INT32, 1);
        expect_basic<double>(SD_BUS_TYPE_DOUBLE, 2.2);
        expect_basic<int>(SD_BUS_TYPE_INT32, c);
        expect_basic_string(SD_BUS_TYPE_STRING, s1.c_str());
        expect_basic<int>(SD_BUS_TYPE_BOOLEAN, false);
        expect_basic_string(SD_BUS_TYPE_STRING, s2);
    }
    new_message().append(1, 2.2, c, s1, false, s2);
}

TEST_F(AppendTest, Array)
{
    const std::array<double, 4> a{1.1, 2.2, 3.3, 4.4};
    static_assert(
        !sdbusplus::message::details::can_append_multiple_v<decltype(a)>);

    {
        testing::InSequence seq;
        expect_open_container(SD_BUS_TYPE_ARRAY, "d");
        for (const auto& i : a)
        {
            expect_basic<double>(SD_BUS_TYPE_DOUBLE, i);
        }
        expect_close_container();
    }
    new_message().append(a);
}

TEST_F(AppendTest, Span)
{
    const std::array<double, 4> a{1.1, 2.2, 3.3, 4.4};
    auto s = std::span{a};
    static_assert(
        !sdbusplus::message::details::can_append_multiple_v<decltype(s)>);

    {
        testing::InSequence seq;
        expect_open_container(SD_BUS_TYPE_ARRAY, "d");
        for (const auto& i : s)
        {
            expect_basic<double>(SD_BUS_TYPE_DOUBLE, i);
        }
        expect_close_container();
    }
    new_message().append(s);
}

TEST_F(AppendTest, Vector)
{
    const std::vector<int> v{1, 2, 3, 4};

    {
        testing::InSequence seq;
        expect_open_container(SD_BUS_TYPE_ARRAY, "i");
        for (const auto& i : v)
        {
            expect_basic<int>(SD_BUS_TYPE_INT32, i);
        }
        expect_close_container();
    }
    new_message().append(v);
}

TEST_F(AppendTest, Set)
{
    const std::set<std::string> s{"one", "two", "eight"};

    {
        testing::InSequence seq;
        expect_open_container(SD_BUS_TYPE_ARRAY, "s");
        for (const auto& i : s)
        {
            expect_basic_string(SD_BUS_TYPE_STRING, i.c_str());
        }
        expect_close_container();
    }
    new_message().append(s);
}

TEST_F(AppendTest, UnorderedSet)
{
    const std::unordered_set<std::string> s{"one", "two", "eight"};

    {
        testing::InSequence seq;
        expect_open_container(SD_BUS_TYPE_ARRAY, "s");
        for (const auto& i : s)
        {
            expect_basic_string(SD_BUS_TYPE_STRING, i.c_str());
        }
        expect_close_container();
    }
    new_message().append(s);
}

TEST_F(AppendTest, Map)
{
    const std::map<int, std::string> m{
        {1, "a"},
        {2, "bc"},
        {3, "def"},
        {4, "ghij"},
    };

    {
        testing::InSequence seq;
        expect_open_container(SD_BUS_TYPE_ARRAY, "{is}");
        for (const auto& i : m)
        {
            expect_open_container(SD_BUS_TYPE_DICT_ENTRY, "is");
            expect_basic<int>(SD_BUS_TYPE_INT32, i.first);
            expect_basic_string(SD_BUS_TYPE_STRING, i.second.c_str());
            expect_close_container();
        }
        expect_close_container();
    }
    new_message().append(m);
}

TEST_F(AppendTest, UnorderedMap)
{
    const std::unordered_map<int, bool> m{
        {1, false},
        {2, true},
        {3, true},
        {4, false},
    };

    {
        testing::InSequence seq;
        expect_open_container(SD_BUS_TYPE_ARRAY, "{ib}");
        for (const auto& i : m)
        {
            expect_open_container(SD_BUS_TYPE_DICT_ENTRY, "ib");
            expect_basic<int>(SD_BUS_TYPE_INT32, i.first);
            expect_basic<int>(SD_BUS_TYPE_BOOLEAN, i.second);
            expect_close_container();
        }
        expect_close_container();
    }
    new_message().append(m);
}

TEST_F(AppendTest, Tuple)
{
    const std::tuple<int, std::string, bool> t{5, "asdf", false};

    {
        testing::InSequence seq;
        expect_open_container(SD_BUS_TYPE_STRUCT, "isb");
        expect_basic<int>(SD_BUS_TYPE_INT32, std::get<0>(t));
        expect_basic_string(SD_BUS_TYPE_STRING, std::get<1>(t).c_str());
        expect_basic<int>(SD_BUS_TYPE_BOOLEAN, std::get<2>(t));
        expect_close_container();
    }
    new_message().append(t);
}

TEST_F(AppendTest, Variant)
{
    const bool b1 = false;
    const std::string s2{"asdf"};
    const std::variant<int, std::string, bool> v1{b1}, v2{s2};

    {
        testing::InSequence seq;
        expect_open_container(SD_BUS_TYPE_VARIANT, "b");
        expect_basic<int>(SD_BUS_TYPE_BOOLEAN, b1);
        expect_close_container();
        expect_open_container(SD_BUS_TYPE_VARIANT, "s");
        expect_basic_string(SD_BUS_TYPE_STRING, s2.c_str());
        expect_close_container();
    }
    new_message().append(v1, v2);
}

TEST_F(AppendTest, LargeCombo)
{
    std::vector<std::array<std::string, 3>> vas{{"a", "b", "c"},
                                                {"d", "", "e"}};
    std::map<std::string, std::variant<int, double>> msv = {
        {"a", 3.3}, {"b", 1}, {"c", 4.4}};

    {
        testing::InSequence seq;

        expect_open_container(SD_BUS_TYPE_ARRAY, "as");
        for (const auto& as : vas)
        {
            expect_open_container(SD_BUS_TYPE_ARRAY, "s");
            for (const auto& s : as)
            {
                expect_basic_string(SD_BUS_TYPE_STRING, s.c_str());
            }
            expect_close_container();
        }
        expect_close_container();

        expect_open_container(SD_BUS_TYPE_ARRAY, "{sv}");
        for (const auto& sv : msv)
        {
            expect_open_container(SD_BUS_TYPE_DICT_ENTRY, "sv");
            expect_basic_string(SD_BUS_TYPE_STRING, sv.first.c_str());
            if (std::holds_alternative<int>(sv.second))
            {
                expect_open_container(SD_BUS_TYPE_VARIANT, "i");
                expect_basic<int>(SD_BUS_TYPE_INT32, std::get<int>(sv.second));
                expect_close_container();
            }
            else
            {
                expect_open_container(SD_BUS_TYPE_VARIANT, "d");
                expect_basic<double>(SD_BUS_TYPE_DOUBLE,
                                     std::get<double>(sv.second));
                expect_close_container();
            }
            expect_close_container();
        }
        expect_close_container();
    }
    new_message().append(vas, msv);
}

} // namespace
