#include <cerrno>
#include <functional>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <memory>
#include <sdeventplus/event.hpp>
#include <sdeventplus/exception.hpp>
#include <sdeventplus/source/child.hpp>
#include <sdeventplus/test/sdevent.hpp>
#include <sys/wait.h>
#include <systemd/sd-event.h>
#include <type_traits>
#include <utility>

namespace sdeventplus
{
namespace source
{
namespace
{

using testing::DoAll;
using testing::Return;
using testing::SaveArg;
using testing::SetArgPointee;

using UniqueEvent = std::unique_ptr<Event, std::function<void(Event*)>>;

class ChildTest : public testing::Test
{
  protected:
    testing::StrictMock<test::SdEventMock> mock;
    sd_event_source* const expected_source =
        reinterpret_cast<sd_event_source*>(1234);
    sd_event* const expected_event = reinterpret_cast<sd_event*>(2345);
    UniqueEvent event = make_event(expected_event);

    UniqueEvent make_event(sd_event* event)
    {
        auto deleter = [this, event](Event* e) {
            EXPECT_CALL(this->mock, sd_event_unref(event))
                .WillOnce(Return(nullptr));
            delete e;
        };
        return UniqueEvent(new Event(event, std::false_type(), &mock), deleter);
    }

    void expect_destruct()
    {
        {
            testing::InSequence sequence;
            EXPECT_CALL(mock, sd_event_source_set_enabled(expected_source,
                                                          SD_EVENT_OFF))
                .WillOnce(Return(0));
            EXPECT_CALL(mock, sd_event_source_unref(expected_source))
                .WillOnce(Return(nullptr));
        }
        EXPECT_CALL(mock, sd_event_unref(expected_event))
            .WillOnce(Return(nullptr));
    }
};

TEST_F(ChildTest, ConstructSuccess)
{
    const pid_t pid = 50;
    const int options = WEXITED;

    EXPECT_CALL(mock, sd_event_ref(expected_event))
        .WillOnce(Return(expected_event));
    sd_event_child_handler_t handler;
    EXPECT_CALL(mock, sd_event_add_child(expected_event, testing::_, pid,
                                         options, testing::_, nullptr))
        .WillOnce(DoAll(SetArgPointee<1>(expected_source), SaveArg<4>(&handler),
                        Return(0)));
    void* userdata;
    EXPECT_CALL(mock, sd_event_source_set_userdata(expected_source, testing::_))
        .WillOnce(DoAll(SaveArg<1>(&userdata), Return(nullptr)));
    int completions = 0;
    const siginfo_t* return_si;
    Child::Callback callback = [&](Child&, const siginfo_t* si) {
        return_si = si;
        completions++;
    };
    Child child(*event, pid, options, std::move(callback));
    EXPECT_FALSE(callback);
    EXPECT_EQ(&child, userdata);
    EXPECT_EQ(0, completions);

    const siginfo_t* expected_si = reinterpret_cast<siginfo_t*>(865);
    EXPECT_EQ(0, handler(nullptr, expected_si, &child));
    EXPECT_EQ(1, completions);
    EXPECT_EQ(expected_si, return_si);

    expect_destruct();
}

TEST_F(ChildTest, ConstructError)
{
    const pid_t pid = 50;
    const int options = WEXITED;

    EXPECT_CALL(mock, sd_event_add_child(expected_event, testing::_, pid,
                                         options, testing::_, nullptr))
        .WillOnce(Return(-EINVAL));
    int completions = 0;
    Child::Callback callback = [&completions](Child&, const siginfo_t*) {
        completions++;
    };
    EXPECT_THROW(Child(*event, pid, options, std::move(callback)),
                 SdEventError);
    EXPECT_TRUE(callback);
    EXPECT_EQ(0, completions);
}

class ChildMethodTest : public ChildTest
{
  protected:
    std::unique_ptr<Child> child;

    void SetUp()
    {
        const pid_t pid = 50;
        const int options = WEXITED;

        EXPECT_CALL(mock, sd_event_ref(expected_event))
            .WillOnce(Return(expected_event));
        EXPECT_CALL(mock, sd_event_add_child(expected_event, testing::_, pid,
                                             options, testing::_, nullptr))
            .WillOnce(DoAll(SetArgPointee<1>(expected_source), Return(0)));
        EXPECT_CALL(mock,
                    sd_event_source_set_userdata(expected_source, testing::_))
            .WillOnce(Return(nullptr));
        child = std::make_unique<Child>(*event, pid, options,
                                        [](Child&, const siginfo_t*) {});
    }

    void TearDown()
    {
        expect_destruct();
        child.reset();
    }
};

TEST_F(ChildMethodTest, GetPidSuccess)
{
    const pid_t pid = 32;
    EXPECT_CALL(mock,
                sd_event_source_get_child_pid(expected_source, testing::_))
        .WillOnce(DoAll(SetArgPointee<1>(pid), Return(0)));
    EXPECT_EQ(pid, child->get_pid());
}

TEST_F(ChildMethodTest, GetPidError)
{
    EXPECT_CALL(mock,
                sd_event_source_get_child_pid(expected_source, testing::_))
        .WillOnce(Return(-EINVAL));
    EXPECT_THROW(child->get_pid(), SdEventError);
}

} // namespace
} // namespace source
} // namespace sdeventplus
