#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
