#include <array>
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include <map>
#include <sdbusplus/message.hpp>
#include <sdbusplus/test/sdbus_mock.hpp>
#include <set>
#include <string>
#include <systemd/sd-bus-protocol.h>
#include <tuple>
#include <unordered_map>
#include <vector>

namespace
{

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

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::message 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_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)
{
    expect_basic<int>(SD_BUS_TYPE_INT32, 1);
    new_message().append(1);
}

TEST_F(AppendTest, LValueInt)
{
    const int a = 1;
    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";
    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"};
    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, 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};

    {
        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, 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, 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 sdbusplus::message::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, sdbusplus::message::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 (sv.second.is<int>())
            {
                expect_open_container(SD_BUS_TYPE_VARIANT, "i");
                expect_basic<int>(SD_BUS_TYPE_INT32, sv.second.get<int>());
                expect_close_container();
            }
            else
            {
                expect_open_container(SD_BUS_TYPE_VARIANT, "d");
                expect_basic<double>(SD_BUS_TYPE_DOUBLE,
                                     sv.second.get<double>());
                expect_close_container();
            }
            expect_close_container();
        }
        expect_close_container();
    }
    new_message().append(vas, msv);
}

} // namespace
