#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
