#include "evdev.hpp"
#include "monitor.hpp"

#include <linux/input.h>
#include <sys/types.h>

#include <chrono>
#include <iostream>
#include <string>

#include <gtest/gtest.h>

using namespace phosphor::gpio;

// Exit helper. Ideally should be class but need
// this to be used inside a static method.
bool completed{};

class GpioTest : public ::testing::Test
{
  public:
    static constexpr auto DEVICE = "/tmp/test_fifo";

    // systemd event handler
    sd_event* events;

    // Really needed just for the constructor
    decltype(input_event::code) code = 10;

    // Really needed just for the constructor
    decltype(input_event::value) value = 10;

    // Need this so that events can be initialized.
    int rc;

    // Gets called as part of each TEST_F construction
    GpioTest() : rc(sd_event_default(&events))
    {
        // Check for successful creation of event handler
        EXPECT_GE(rc, 0);

        // FIFO created to simulate data available
        EXPECT_EQ(0, mknod(DEVICE, S_IFIFO | 0666, 0));
    }

    // Gets called as part of each TEST_F destruction
    ~GpioTest()
    {
        EXPECT_EQ(0, remove(DEVICE));

        events = sd_event_unref(events);
        EXPECT_EQ(events, nullptr);
    }

    // Callback handler on data
    static int callbackHandler(sd_event_source* es, int fd, uint32_t revents,
                               void* userData)
    {
        std::cout << "Event fired" << std::endl;
        completed = true;
        return 0;
    }
};

/** @brief Makes sure that event never comes for 3 seconds
 */
TEST_F(GpioTest, noEventIn3Seconds)
{
    using namespace std::chrono;

    phosphor::gpio::EventPtr eventP{events};
    events = nullptr;

    const std::string emptyTarget = "";
    Monitor gpio(DEVICE, code, value, emptyTarget, eventP, false,
                 callbackHandler, false);

    // Waiting 3 seconds and check if the completion status is set
    int count = 0;
    while (count < 3)
    {
        // Returns -0- on timeout and positive number on dispatch
        auto sleepTime = duration_cast<microseconds>(seconds(1));
        if (!sd_event_run(eventP.get(), sleepTime.count()))
        {
            count++;
        }
    }
    EXPECT_EQ(false, completed);

    // 3 to cater to another uptick that happens prior to breaking.
    EXPECT_EQ(3, count);
}

/** @brief Pump data in the middle and expect the callback to be invoked */
TEST_F(GpioTest, pumpDataAndExpectCallBack)
{
    using namespace std::chrono;

    phosphor::gpio::EventPtr eventP{events};
    events = nullptr;

    const std::string emptyTarget = "";
    Monitor gpio(DEVICE, code, value, emptyTarget, eventP, false,
                 callbackHandler, false);

    // Pump the data in the middle
    int count = 0;
    while (count < 2 && !completed)
    {
        if (count == 1)
        {
            auto pumpData = std::string("echo 'foo' > ") + DEVICE;
            EXPECT_GE(0, system(pumpData.c_str()));
        }

        // Returns -0- on timeout
        auto sleepTime = duration_cast<microseconds>(seconds(1));
        if (!sd_event_run(eventP.get(), sleepTime.count()))
        {
            count++;
        }
    }
    EXPECT_EQ(true, completed);
    EXPECT_EQ(1, count);
}
