#include <linux/gpio.h>

#include <gpioplus/event.hpp>
#include <gpioplus/test/sys.hpp>

#include <cerrno>
#include <cstring>
#include <memory>
#include <optional>
#include <stdexcept>
#include <string>
#include <system_error>

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

namespace gpioplus
{
namespace
{

using testing::Assign;
using testing::DoAll;
using testing::Return;
using testing::SaveArgPointee;
using testing::SetArgPointee;
using testing::WithArg;

TEST(EventFlags, EventFlagsToInt)
{
    EventFlags event_flags;
    event_flags.rising_edge = true;
    event_flags.falling_edge = true;
    EXPECT_EQ(GPIOEVENT_REQUEST_RISING_EDGE | GPIOEVENT_REQUEST_FALLING_EDGE,
              event_flags.toInt());

    event_flags.rising_edge = false;
    event_flags.falling_edge = false;
    EXPECT_EQ(0, event_flags.toInt());
}

class EventTest : public testing::Test
{
  protected:
    const int chip_fd = 1234;
    const int event_fd = 2345;
    testing::StrictMock<test::SysMock> mock;
    std::unique_ptr<Chip> chip;

    void SetUp()
    {
        EXPECT_CALL(mock, open(testing::_, testing::_))
            .WillOnce(Return(chip_fd));
        chip = std::make_unique<Chip>(0, &mock);
    }

    void TearDown()
    {
        EXPECT_CALL(mock, close(chip_fd)).WillOnce(Return(0));
        chip.reset();
    }
};

TEST_F(EventTest, ConstructSuccess)
{
    const uint32_t line_offset = 3;
    const std::string label{"test"};
    HandleFlags handle_flags(LineFlags(0));
    EventFlags event_flags;
    event_flags.rising_edge = true;
    event_flags.falling_edge = false;

    struct gpioevent_request req, ret;
    ret.fd = event_fd;
    EXPECT_CALL(mock, gpio_get_lineevent(chip_fd, testing::_))
        .WillOnce(
            DoAll(SaveArgPointee<1>(&req), SetArgPointee<1>(ret), Return(0)));
    Event event(*chip, line_offset, handle_flags, event_flags, label.c_str());

    EXPECT_EQ(event_fd, *event.getFd());
    EXPECT_EQ(line_offset, req.lineoffset);
    EXPECT_EQ(GPIOHANDLE_REQUEST_INPUT, req.handleflags);
    EXPECT_EQ(GPIOEVENT_REQUEST_RISING_EDGE, req.eventflags);
    EXPECT_EQ(label, req.consumer_label);

    EXPECT_CALL(mock, close(event_fd)).WillOnce(Return(0));
}

TEST_F(EventTest, ConstructLabelTooLong)
{
    const size_t large_size = sizeof(
        reinterpret_cast<struct gpioevent_request*>(NULL)->consumer_label);
    EXPECT_THROW(Event(*chip, 0, HandleFlags(), EventFlags(),
                       std::string(large_size, '1')),
                 std::invalid_argument);
}

TEST_F(EventTest, ConstructFailure)
{
    const uint32_t line_offset = 3;
    const std::string label{"test"};
    HandleFlags handle_flags(LineFlags(0));
    EventFlags event_flags;
    event_flags.rising_edge = false;
    event_flags.falling_edge = false;

    struct gpioevent_request req;
    EXPECT_CALL(mock, gpio_get_lineevent(chip_fd, testing::_))
        .WillOnce(DoAll(SaveArgPointee<1>(&req), Return(-EINVAL)));
    EXPECT_THROW(
        Event(*chip, line_offset, handle_flags, event_flags, label.c_str()),
        std::system_error);

    EXPECT_EQ(line_offset, req.lineoffset);
    EXPECT_EQ(GPIOHANDLE_REQUEST_INPUT, req.handleflags);
    EXPECT_EQ(0, req.eventflags);
    EXPECT_EQ(label, req.consumer_label);
}

class EventMethodTest : public EventTest
{
  protected:
    std::unique_ptr<Event> event;

    void SetUp()
    {
        EventTest::SetUp();
        struct gpioevent_request ret;
        ret.fd = event_fd;
        EXPECT_CALL(mock, gpio_get_lineevent(chip_fd, testing::_))
            .WillOnce(DoAll(SetArgPointee<1>(ret), Return(0)));
        event = std::make_unique<Event>(*chip, 0, HandleFlags(LineFlags(0)),
                                        EventFlags(), "method");
    }

    void TearDown()
    {
        EXPECT_CALL(mock, close(event_fd)).WillOnce(Return(0));
        event.reset();
        EventTest::TearDown();
    }
};

ACTION_P(WriteStruct, data)
{
    memcpy(arg0, &data, sizeof(data));
}

TEST_F(EventMethodTest, ReadSuccess)
{
    struct gpioevent_data ret;
    ret.timestamp = 5;
    ret.id = 15;
    EXPECT_CALL(mock, read(event_fd, testing::_, sizeof(struct gpioevent_data)))
        .WillOnce(DoAll(WithArg<1>(WriteStruct(ret)), Return(sizeof(ret))));
    std::optional<Event::Data> data = event->read();
    EXPECT_TRUE(data);
    EXPECT_EQ(ret.timestamp, data->timestamp.count());
    EXPECT_EQ(ret.id, data->id);
}

TEST_F(EventMethodTest, ReadAgain)
{
    EXPECT_CALL(mock, read(event_fd, testing::_, sizeof(struct gpioevent_data)))
        .WillOnce(DoAll(Assign(&errno, EAGAIN), Return(-1)));
    EXPECT_EQ(std::nullopt, event->read());
}

TEST_F(EventMethodTest, ReadFailure)
{
    EXPECT_CALL(mock, read(event_fd, testing::_, sizeof(struct gpioevent_data)))
        .WillOnce(DoAll(Assign(&errno, EINVAL), Return(-1)));
    EXPECT_THROW(event->read(), std::system_error);
}

TEST_F(EventMethodTest, ReadTooSmall)
{
    EXPECT_CALL(mock, read(event_fd, testing::_, sizeof(struct gpioevent_data)))
        .WillOnce(Return(1));
    EXPECT_THROW(event->read(), std::runtime_error);
}

TEST_F(EventMethodTest, GetValueSuccess)
{
    struct gpiohandle_data data;
    data.values[0] = 1;
    EXPECT_CALL(mock, gpiohandle_get_line_values(event_fd, testing::_))
        .WillOnce(DoAll(SetArgPointee<1>(data), Return(0)));
    EXPECT_EQ(data.values[0], event->getValue());
}

TEST_F(EventMethodTest, GetValueFailure)
{
    EXPECT_CALL(mock, gpiohandle_get_line_values(event_fd, testing::_))
        .WillOnce(Return(-EINVAL));
    EXPECT_THROW(event->getValue(), std::system_error);
}

} // namespace
} // namespace gpioplus
