#include "gpio_monitor.hpp"

#include "constants.hpp"
#include "logger.hpp"
#include "types.hpp"
#include "utility/dbus_utility.hpp"
#include "utility/json_utility.hpp"

#include <boost/asio.hpp>
#include <boost/bind/bind.hpp>
#include <gpiod.hpp>

namespace vpd
{
void GpioEventHandler::handleChangeInGpioPin(const bool& i_isFruPresent)
{
    try
    {
        if (i_isFruPresent)
        {
            types::VPDMapVariant l_parsedVpd =
                m_worker->parseVpdFile(m_fruPath);

            if (std::holds_alternative<std::monostate>(l_parsedVpd))
            {
                throw std::runtime_error(
                    "VPD parsing failed for " + std::string(m_fruPath));
            }

            types::ObjectMap l_dbusObjectMap;
            m_worker->populateDbus(l_parsedVpd, l_dbusObjectMap, m_fruPath);

            if (l_dbusObjectMap.empty())
            {
                throw std::runtime_error("Failed to create D-bus object map.");
            }

            if (!dbusUtility::callPIM(move(l_dbusObjectMap)))
            {
                throw std::runtime_error("call PIM failed");
            }
        }
        else
        {
            m_worker->deleteFruVpd(jsonUtility::getInventoryObjPathFromJson(
                m_worker->getSysCfgJsonObj(), m_fruPath));
        }
    }
    catch (std::exception& l_ex)
    {
        logging::logMessage(std::string(l_ex.what()));
    }
}

void GpioEventHandler::handleTimerExpiry(
    const boost::system::error_code& i_errorCode,
    const std::shared_ptr<boost::asio::steady_timer>& i_timerObj)
{
    if (i_errorCode == boost::asio::error::operation_aborted)
    {
        logging::logMessage("Timer aborted for GPIO pin");
        return;
    }

    if (i_errorCode)
    {
        logging::logMessage("Timer wait failed for gpio pin" +
                            std::string(i_errorCode.message()));
        return;
    }

    bool l_currentPresencePinValue = jsonUtility::processGpioPresenceTag(
        m_worker->getSysCfgJsonObj(), m_fruPath, "pollingRequired",
        "hotPlugging");

    if (m_prevPresencePinValue != l_currentPresencePinValue)
    {
        m_prevPresencePinValue = l_currentPresencePinValue;
        handleChangeInGpioPin(l_currentPresencePinValue);
    }

    i_timerObj->expires_at(std::chrono::steady_clock::now() +
                           std::chrono::seconds(constants::VALUE_5));
    i_timerObj->async_wait(
        boost::bind(&GpioEventHandler::handleTimerExpiry, this,
                    boost::asio::placeholders::error, i_timerObj));
}

void GpioEventHandler::setEventHandlerForGpioPresence(
    const std::shared_ptr<boost::asio::io_context>& i_ioContext)
{
    m_prevPresencePinValue = jsonUtility::processGpioPresenceTag(
        m_worker->getSysCfgJsonObj(), m_fruPath, "pollingRequired",
        "hotPlugging");

    static std::vector<std::shared_ptr<boost::asio::steady_timer>> l_timers;

    auto l_timerObj = make_shared<boost::asio::steady_timer>(
        *i_ioContext, std::chrono::seconds(constants::VALUE_5));

    l_timerObj->async_wait(
        boost::bind(&GpioEventHandler::handleTimerExpiry, this,
                    boost::asio::placeholders::error, l_timerObj));

    l_timers.push_back(l_timerObj);
}

void GpioMonitor::initHandlerForGpio(
    const std::shared_ptr<boost::asio::io_context>& i_ioContext,
    const std::shared_ptr<Worker>& i_worker)
{
    std::vector<std::string> l_gpioPollingRequiredFrusList =
        jsonUtility::getListOfGpioPollingFrus(m_sysCfgJsonObj);

    for (const auto& l_fruPath : l_gpioPollingRequiredFrusList)
    {
        std::shared_ptr<GpioEventHandler> l_gpioEventHandlerObj =
            std::make_shared<GpioEventHandler>(l_fruPath, i_worker,
                                               i_ioContext);

        m_gpioEventHandlerObjects.push_back(l_gpioEventHandlerObj);
    }
}
} // namespace vpd
