#include <systemd/sd-event.h>

#include <sdeventplus/event.hpp>
#include <sdeventplus/exception.hpp>
#include <sdeventplus/internal/sdevent.hpp>
#include <sdeventplus/source/base.hpp>
#include <sdeventplus/test/sdevent.hpp>
#include <sdeventplus/types.hpp>

#include <cerrno>
#include <functional>
#include <memory>
#include <optional>
#include <string>
#include <tuple>
#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::SaveArg;
using testing::SetArgPointee;

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

class BaseImplData;

class BaseImpl : public Base
{
  public:
    BaseImpl(const Event& event, sd_event_source* source, std::false_type);

    BaseImpl(const BaseImpl& other, sdeventplus::internal::NoOwn) :
        Base(other, sdeventplus::internal::NoOwn())
    {}

    using Base::get_prepare;
};

class BaseImplData : public BaseImpl, public detail::BaseData
{
  public:
    BaseImplData(const BaseImpl& base) :
        BaseImpl(base, sdeventplus::internal::NoOwn()), BaseData(base)
    {}
};

BaseImpl::BaseImpl(const Event& event, sd_event_source* source,
                   std::false_type) : Base(event, source, std::false_type())
{
    set_userdata(std::make_unique<BaseImplData>(*this));
}

class BaseTest : public testing::Test
{
  protected:
    testing::StrictMock<test::SdEventMock> mock;
    sd_event_source* const expected_source =
        reinterpret_cast<sd_event_source*>(1234);
    sd_event_source* const expected_source2 =
        reinterpret_cast<sd_event_source*>(3456);
    sd_event* const expected_event = reinterpret_cast<sd_event*>(2345);
    sd_event* const expected_event2 = reinterpret_cast<sd_event*>(4567);

    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);
    }

    // Using a unique_ptr to make sure we don't get any superfluous moves or
    // copies.
    std::tuple<std::unique_ptr<BaseImpl>, std::function<void()>>
        make_base(const Event& event, sd_event_source* source)
    {
        EXPECT_CALL(mock, sd_event_ref(event.get()))
            .WillOnce(Return(event.get()));
        sd_event_destroy_t destroy;
        void* userdata;
        {
            testing::InSequence seq;
            EXPECT_CALL(
                mock, sd_event_source_set_destroy_callback(source, testing::_))
                .WillOnce(DoAll(SaveArg<1>(&destroy), Return(0)));
            EXPECT_CALL(mock, sd_event_source_set_userdata(source, testing::_))
                .WillOnce(DoAll(SaveArg<1>(&userdata), Return(nullptr)));
        }
        auto ret = std::make_unique<BaseImpl>(event, source, std::false_type());
        EXPECT_CALL(mock, sd_event_source_get_userdata(source))
            .WillRepeatedly(Return(userdata));
        EXPECT_NE(ret.get(), userdata);
        EXPECT_EQ(source, ret->get());
        EXPECT_NE(&event, &ret->get_event());
        EXPECT_EQ(event.get(), ret->get_event().get());
        EXPECT_FALSE(ret->get_prepare());
        return {std::move(ret), std::bind(destroy, userdata)};
    }

    void set_prepare_placeholder(BaseImpl& base)
    {
        EXPECT_CALL(mock, sd_event_source_set_prepare(base.get(), testing::_))
            .WillOnce(Return(0));
        base.set_prepare([](Base&) {});
        EXPECT_TRUE(base.get_prepare());
    }

    void empty_base(BaseImpl&& other)
    {
        BaseImpl mover(std::move(other));
        EXPECT_THROW(other.get(), std::bad_optional_access);
        EXPECT_THROW(other.get_event().get(), std::bad_optional_access);
        EXPECT_THROW(other.get_prepare(), std::bad_optional_access);

        expect_base_destruct(mover.get_event(), mover.get());
    }

    void expect_base_destruct(const Event& event, sd_event_source* source)
    {
        EXPECT_CALL(mock, sd_event_source_unref(source))
            .WillOnce(Return(nullptr));
        EXPECT_CALL(mock, sd_event_unref(event.get()))
            .WillOnce(Return(nullptr));
    }
};

TEST_F(BaseTest, NewBaseFail)
{
    EXPECT_CALL(mock, sd_event_ref(expected_event))
        .WillOnce(Return(expected_event));
    EXPECT_CALL(
        mock, sd_event_source_set_destroy_callback(expected_source, testing::_))
        .WillOnce(Return(-EINVAL));
    expect_base_destruct(*event, expected_source);
    EXPECT_THROW(BaseImpl(*event, expected_source, std::false_type()),
                 SdEventError);
}

TEST_F(BaseTest, NewBaseNoRef)
{
    EXPECT_CALL(mock, sd_event_ref(expected_event))
        .WillOnce(Return(expected_event));
    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)));
    }
    BaseImpl source(*event, expected_source, std::false_type());
    EXPECT_NE(&source, userdata);
    EXPECT_EQ(expected_source, source.get());
    EXPECT_NE(event.get(), &source.get_event());
    EXPECT_EQ(expected_event, source.get_event().get());

    EXPECT_CALL(mock, sd_event_source_get_userdata(expected_source))
        .WillOnce(Return(userdata));
    EXPECT_FALSE(source.get_prepare());

    expect_base_destruct(*event, expected_source);
    destroy(userdata);
}

TEST_F(BaseTest, UserdataOutlives)
{
    EXPECT_CALL(mock, sd_event_ref(expected_event))
        .WillOnce(Return(expected_event));
    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)));
    }
    auto source =
        std::make_unique<BaseImpl>(*event, expected_source, std::false_type());
    EXPECT_CALL(mock, sd_event_source_get_userdata(expected_source))
        .WillRepeatedly(Return(userdata));
    EXPECT_FALSE(source->get_prepare());

    expect_base_destruct(*event, expected_source);
    source.reset();
    EXPECT_FALSE(reinterpret_cast<BaseImpl*>(userdata)->get_prepare());
    destroy(userdata);
}

TEST_F(BaseTest, CopyCorrectness)
{
    std::unique_ptr<BaseImpl> base1, base2;
    std::function<void()> destroy;
    std::tie(base1, destroy) = make_base(*event, expected_source);
    set_prepare_placeholder(*base1);
    EXPECT_TRUE(base1->get_prepare());

    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));
    base2 = std::make_unique<BaseImpl>(*base1);
    EXPECT_EQ(&base1->get_prepare(), &base2->get_prepare());

    empty_base(std::move(*base1));
    EXPECT_THROW(base1->get_prepare(), std::bad_optional_access);
    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));
    *base1 = *base2;
    EXPECT_EQ(&base1->get_prepare(), &base2->get_prepare());

    expect_base_destruct(*event, expected_source);
    base2.reset();
    expect_base_destruct(*event, expected_source);
    base1.reset();
    destroy();
}

class BaseMethodTest : public BaseTest
{
  protected:
    std::unique_ptr<BaseImpl> base;
    std::function<void()> destroy;

    void SetUp()
    {
        std::tie(base, destroy) = make_base(*event, expected_source);
    }

    void TearDown()
    {
        expect_base_destruct(base->get_event(), base->get());
        base.reset();
        destroy();
    }
};

TEST_F(BaseMethodTest, GetDescriptionSuccess)
{
    const char* expected = "test_desc";
    EXPECT_CALL(mock,
                sd_event_source_get_description(expected_source, testing::_))
        .WillOnce(DoAll(SetArgPointee<1>(expected), Return(0)));
    // Intentionally comparing pointers to make sure no copying is happening
    EXPECT_EQ(expected, base->get_description());
}

TEST_F(BaseMethodTest, GetDescriptionError)
{
    EXPECT_CALL(mock,
                sd_event_source_get_description(expected_source, testing::_))
        .WillOnce(Return(-EINVAL));
    EXPECT_THROW(base->get_description(), SdEventError);
}

TEST_F(BaseMethodTest, SetDescriptionSuccess)
{
    const char* expected = "test desc";
    // Intentionally comparing pointers to make sure no copying is happening
    EXPECT_CALL(mock,
                sd_event_source_set_description(expected_source, expected))
        .WillOnce(Return(0));
    base->set_description(expected);
}

TEST_F(BaseMethodTest, SetDescriptionError)
{
    const char* expected = "test desc";
    // Intentionally comparing pointers to make sure no copying is happening
    EXPECT_CALL(mock,
                sd_event_source_set_description(expected_source, expected))
        .WillOnce(Return(-EINVAL));
    EXPECT_THROW(base->set_description(expected), SdEventError);
}

TEST_F(BaseMethodTest, SetPrepareCallback)
{
    bool completed = false;
    Base::Callback callback = [&completed](Base&) { completed = true; };
    sd_event_handler_t event_handler;
    EXPECT_CALL(mock, sd_event_source_set_prepare(expected_source, testing::_))
        .WillOnce(DoAll(SaveArg<1>(&event_handler), Return(0)));
    base->set_prepare(std::move(callback));
    EXPECT_TRUE(base->get_prepare());
    EXPECT_FALSE(callback);
    EXPECT_FALSE(completed);

    EXPECT_EQ(0, event_handler(nullptr, base.get()));
    EXPECT_TRUE(completed);
}

TEST_F(BaseMethodTest, SetPrepareCallbackNoUserdata)
{
    Base::Callback callback = [](Base&) {};
    sd_event_handler_t event_handler;
    EXPECT_CALL(mock, sd_event_source_set_prepare(expected_source, testing::_))
        .WillOnce(DoAll(SaveArg<1>(&event_handler), Return(0)));
    base->set_prepare(std::move(callback));
    EXPECT_TRUE(base->get_prepare());
    EXPECT_FALSE(callback);

    EXPECT_EQ(-EINVAL, event_handler(nullptr, nullptr));
}

TEST_F(BaseMethodTest, SetPrepareError)
{
    EXPECT_CALL(mock, sd_event_source_set_prepare(expected_source, testing::_))
        .WillOnce(Return(0));
    base->set_prepare([](Base&) {});
    EXPECT_TRUE(base->get_prepare());

    Base::Callback callback = [](Base&) {};
    EXPECT_CALL(mock, sd_event_source_set_prepare(expected_source, testing::_))
        .WillOnce(Return(-EINVAL));
    EXPECT_THROW(base->set_prepare(std::move(callback)), SdEventError);
    EXPECT_FALSE(base->get_prepare());
    EXPECT_TRUE(callback);
}

TEST_F(BaseMethodTest, SetPrepareNull)
{
    EXPECT_CALL(mock, sd_event_source_set_prepare(expected_source, testing::_))
        .WillOnce(Return(0));
    base->set_prepare([](Base&) {});
    EXPECT_TRUE(base->get_prepare());

    EXPECT_CALL(mock, sd_event_source_set_prepare(expected_source, nullptr))
        .WillOnce(Return(0));
    base->set_prepare(nullptr);
    EXPECT_FALSE(base->get_prepare());
}

TEST_F(BaseMethodTest, GetPendingSuccess)
{
    EXPECT_CALL(mock, sd_event_source_get_pending(expected_source))
        .WillOnce(Return(0));
    EXPECT_FALSE(base->get_pending());
    EXPECT_CALL(mock, sd_event_source_get_pending(expected_source))
        .WillOnce(Return(4));
    EXPECT_TRUE(base->get_pending());
}

TEST_F(BaseMethodTest, GetPendingError)
{
    EXPECT_CALL(mock, sd_event_source_get_pending(expected_source))
        .WillOnce(Return(-EINVAL));
    EXPECT_THROW(base->get_pending(), SdEventError);
}

TEST_F(BaseMethodTest, GetPrioritySuccess)
{
    EXPECT_CALL(mock, sd_event_source_get_priority(expected_source, testing::_))
        .WillOnce(DoAll(SetArgPointee<1>(1024), Return(0)));
    EXPECT_EQ(1024, base->get_priority());
}

TEST_F(BaseMethodTest, GetPriorityError)
{
    EXPECT_CALL(mock, sd_event_source_get_priority(expected_source, testing::_))
        .WillOnce(Return(-EINVAL));
    EXPECT_THROW(base->get_priority(), SdEventError);
}

TEST_F(BaseMethodTest, SetPrioritySuccess)
{
    EXPECT_CALL(mock, sd_event_source_set_priority(expected_source, 1024))
        .WillOnce(Return(0));
    base->set_priority(1024);
}

TEST_F(BaseMethodTest, SetPriorityError)
{
    EXPECT_CALL(mock, sd_event_source_set_priority(expected_source, 1024))
        .WillOnce(Return(-EINVAL));
    EXPECT_THROW(base->set_priority(1024), SdEventError);
}

TEST_F(BaseMethodTest, GetEnabledSuccess)
{
    EXPECT_CALL(mock, sd_event_source_get_enabled(expected_source, testing::_))
        .WillOnce(DoAll(SetArgPointee<1>(SD_EVENT_ON), Return(0)));
    EXPECT_EQ(Enabled::On, base->get_enabled());
}

TEST_F(BaseMethodTest, GetEnabledError)
{
    EXPECT_CALL(mock, sd_event_source_get_enabled(expected_source, testing::_))
        .WillOnce(Return(-EINVAL));
    EXPECT_THROW(base->get_enabled(), SdEventError);
}

TEST_F(BaseMethodTest, SetEnabledSuccess)
{
    EXPECT_CALL(mock, sd_event_source_set_enabled(expected_source, SD_EVENT_ON))
        .WillOnce(Return(0));
    base->set_enabled(Enabled::On);
}

TEST_F(BaseMethodTest, SetEnabledError)
{
    EXPECT_CALL(mock,
                sd_event_source_set_enabled(expected_source, SD_EVENT_ONESHOT))
        .WillOnce(Return(-EINVAL));
    EXPECT_THROW(base->set_enabled(Enabled::OneShot), SdEventError);
}

TEST_F(BaseMethodTest, GetFloatingSuccess)
{
    EXPECT_CALL(mock, sd_event_source_get_floating(expected_source))
        .WillOnce(Return(2));
    EXPECT_TRUE(base->get_floating());
    EXPECT_CALL(mock, sd_event_source_get_floating(expected_source))
        .WillOnce(Return(0));
    EXPECT_FALSE(base->get_floating());
}

TEST_F(BaseMethodTest, GetFloatingError)
{
    EXPECT_CALL(mock, sd_event_source_get_floating(expected_source))
        .WillOnce(Return(-EINVAL));
    EXPECT_THROW(base->get_floating(), SdEventError);
}

TEST_F(BaseMethodTest, SetFloatingSuccess)
{
    EXPECT_CALL(mock, sd_event_source_set_floating(expected_source, 1))
        .WillOnce(Return(0));
    base->set_floating(true);
}

TEST_F(BaseMethodTest, SetFloatingError)
{
    EXPECT_CALL(mock, sd_event_source_set_floating(expected_source, 1))
        .WillOnce(Return(-EINVAL));
    EXPECT_THROW(base->set_floating(true), SdEventError);
}

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