#include <signal.h>
#include <systemd/sd-event.h>

#include <sdeventplus/event.hpp>
#include <sdeventplus/exception.hpp>
#include <sdeventplus/source/signal.hpp>
#include <sdeventplus/test/sdevent.hpp>

#include <cerrno>
#include <functional>
#include <memory>
#include <type_traits>
#include <utility>

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

namespace sdeventplus
{
namespace source
{
namespace
{

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

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

class SignalTest : 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()
    {
        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(SignalTest, ConstructSuccess)
{
    const int sig = SIGALRM;

    EXPECT_CALL(mock, sd_event_ref(expected_event))
        .WillOnce(Return(expected_event));
    sd_event_signal_handler_t handler;
    EXPECT_CALL(mock, sd_event_add_signal(expected_event, testing::_, sig,
                                          testing::_, nullptr))
        .WillOnce(DoAll(SetArgPointee<1>(expected_source), SaveArg<3>(&handler),
                        Return(0)));
    sd_event_destroy_t destroy;
    void* userdata;
    {
        testing::InSequence seq;
        EXPECT_CALL(mock, sd_event_source_set_destroy_callback(expected_source,
                                                               testing::_))
            .WillOnce(DoAll(SaveArg<1>(&destroy), Return(0)));
        EXPECT_CALL(mock,
                    sd_event_source_set_userdata(expected_source, testing::_))
            .WillOnce(DoAll(SaveArg<1>(&userdata), Return(nullptr)));
        EXPECT_CALL(mock, sd_event_source_get_userdata(expected_source))
            .WillRepeatedly(ReturnPointee(&userdata));
    }
    int completions = 0;
    const struct signalfd_siginfo* return_si;
    Signal::Callback callback =
        [&](Signal&, const struct signalfd_siginfo* si) {
            return_si = si;
            completions++;
        };
    Signal signal(*event, sig, std::move(callback));
    EXPECT_FALSE(callback);
    EXPECT_NE(&signal, userdata);
    EXPECT_EQ(0, completions);

    const struct signalfd_siginfo* expected_si =
        reinterpret_cast<struct signalfd_siginfo*>(865);
    EXPECT_EQ(0, handler(nullptr, expected_si, userdata));
    EXPECT_EQ(1, completions);
    EXPECT_EQ(expected_si, return_si);

    signal.set_callback(std::bind([]() {}));
    EXPECT_EQ(0, handler(nullptr, expected_si, userdata));
    EXPECT_EQ(1, completions);

    expect_destruct();
    destroy(userdata);
}

TEST_F(SignalTest, ConstructError)
{
    const int sig = SIGALRM;

    EXPECT_CALL(mock, sd_event_add_signal(expected_event, testing::_, sig,
                                          testing::_, nullptr))
        .WillOnce(Return(-EINVAL));
    int completions = 0;
    Signal::Callback callback =
        [&completions](Signal&, const struct signalfd_siginfo*) {
            completions++;
        };
    EXPECT_THROW(Signal(*event, sig, std::move(callback)), SdEventError);
    EXPECT_TRUE(callback);
    EXPECT_EQ(0, completions);
}

class SignalMethodTest : public SignalTest
{
  protected:
    std::unique_ptr<Signal> signal;
    sd_event_destroy_t destroy;
    void* userdata;

    void SetUp()
    {
        const int sig = SIGINT;

        EXPECT_CALL(mock, sd_event_ref(expected_event))
            .WillOnce(Return(expected_event));
        EXPECT_CALL(mock, sd_event_add_signal(expected_event, testing::_, sig,
                                              testing::_, nullptr))
            .WillOnce(DoAll(SetArgPointee<1>(expected_source), Return(0)));
        {
            testing::InSequence seq;
            EXPECT_CALL(mock, sd_event_source_set_destroy_callback(
                                  expected_source, testing::_))
                .WillOnce(DoAll(SaveArg<1>(&destroy), Return(0)));
            EXPECT_CALL(
                mock, sd_event_source_set_userdata(expected_source, testing::_))
                .WillOnce(DoAll(SaveArg<1>(&userdata), Return(nullptr)));
            EXPECT_CALL(mock, sd_event_source_get_userdata(expected_source))
                .WillRepeatedly(ReturnPointee(&userdata));
        }
        signal = std::make_unique<Signal>(
            *event, sig, [](Signal&, const struct signalfd_siginfo*) {});
    }

    void TearDown()
    {
        expect_destruct();
        signal.reset();
        destroy(userdata);
    }
};

TEST_F(SignalMethodTest, Copy)
{
    EXPECT_CALL(mock, sd_event_ref(expected_event))
        .WillOnce(Return(expected_event));
    EXPECT_CALL(mock, sd_event_source_ref(expected_source))
        .WillOnce(Return(expected_source));
    auto signal2 = std::make_unique<Signal>(*signal);
    {
        EXPECT_CALL(mock, sd_event_ref(expected_event))
            .WillOnce(Return(expected_event));
        EXPECT_CALL(mock, sd_event_source_ref(expected_source))
            .WillOnce(Return(expected_source));
        Signal signal3(*signal);

        expect_destruct();
        EXPECT_CALL(mock, sd_event_ref(expected_event))
            .WillOnce(Return(expected_event));
        EXPECT_CALL(mock, sd_event_source_ref(expected_source))
            .WillOnce(Return(expected_source));
        *signal2 = signal3;

        expect_destruct();
    }

    // Delete the original signal
    signal2.swap(signal);
    expect_destruct();
    signal2.reset();

    // Make sure our new copy can still access data
    signal->set_callback(nullptr);
}

TEST_F(SignalMethodTest, GetSignalSuccess)
{
    const int sig = SIGTERM;
    EXPECT_CALL(mock, sd_event_source_get_signal(expected_source))
        .WillOnce(Return(sig));
    EXPECT_EQ(sig, signal->get_signal());
}

TEST_F(SignalMethodTest, GetSignalError)
{
    EXPECT_CALL(mock, sd_event_source_get_signal(expected_source))
        .WillOnce(Return(-EINVAL));
    EXPECT_THROW(signal->get_signal(), SdEventError);
}

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