#pragma once
#include <string>
#include <systemd/sd-event.h>
#include <libevdev/libevdev.h>
#include "file.hpp"

namespace phosphor
{
namespace gpio
{

/* Need a custom deleter for freeing up sd_event */
struct EventDeleter
{
    void operator()(sd_event* event) const
    {
        event = sd_event_unref(event);
    }
};
using EventPtr = std::unique_ptr<sd_event, EventDeleter>;

/* Need a custom deleter for freeing up sd_event_source */
struct EventSourceDeleter
{
    void operator()(sd_event_source* eventSource) const
    {
        eventSource = sd_event_source_unref(eventSource);
    }
};
using EventSourcePtr = std::unique_ptr<sd_event_source, EventSourceDeleter>;

/* Need a custom deleter for freeing up evdev struct */
struct FreeEvDev
{
    void operator()(struct libevdev* device) const
    {
        libevdev_free(device);
    }
};
using EvdevPtr = std::unique_ptr<struct libevdev, FreeEvDev>;

/** @class Evdev
 *  @brief Responsible for catching GPIO state changes conditions and taking
 *  actions
 */
class Evdev
{

        using Property = std::string;
        using Value = sdbusplus::message::variant<bool, std::string>;
        // Association between property and its value
        using PropertyMap = std::map<Property, Value>;
        using Interface = std::string;
        // Association between interface and the D-Bus property
        using InterfaceMap = std::map<Interface, PropertyMap>;
        using Object = sdbusplus::message::object_path;
        // Association between object and the interface
        using ObjectMap = std::map<Object, InterfaceMap>;

    public:
        Evdev() = delete;
        ~Evdev() = default;
        Evdev(const Evdev&) = delete;
        Evdev& operator=(const Evdev&) = delete;
        Evdev(Evdev&&) = delete;
        Evdev& operator=(Evdev&&) = delete;

        /** @brief Constructs Evdev object.
         *
         *  @param[in] path      - Device path to read for GPIO pin state
         *  @param[in] key       - GPIO key to monitor
         *  @param[in] event     - sd_event handler
         *  @param[in] handler   - IO callback handler.
         *  @param[in] useEvDev  - Whether to use EvDev to retrieve events
         */
        Evdev(const std::string& path,
              const unsigned int key,
              EventPtr& event,
              sd_event_io_handler_t handler,
              bool useEvDev = true) :
            path(path),
            key(key),
            event(event),
            callbackHandler(handler),
            fd(openDevice())

        {
            if (useEvDev)
            {
                // If we are asked to use EvDev, do that initialization.
                initEvDev();
            }

            // Register callback handler when FD has some data
            registerCallback();
        }

    protected:
        /** @brief Device path to read for GPIO pin state */
        const std::string path;

        /** @brief GPIO key to monitor */
        const unsigned int key;

        /** @brief Event structure */
        EvdevPtr devicePtr;

        /** @brief Monitor to sd_event */
        EventPtr& event;

        /** @brief Callback handler when the FD has some data */
        sd_event_io_handler_t callbackHandler;

        /** @brief event source */
        EventSourcePtr eventSource;

        /** @brief Opens the device and populates the descriptor */
        int openDevice();

        /** @brief attaches FD to events and sets up callback handler */
        void registerCallback();

        /** @brief File descriptor manager */
        FileDescriptor fd;

        /** @brief Initializes evdev handle with the fd */
        void initEvDev();
};

} // namespace gpio
} // namespace phosphor
