#include "serial_uart_mux.hpp"

#include "xyz/openbmc_project/Chassis/Buttons/HostSelector/client.hpp"
#include "xyz/openbmc_project/Chassis/Buttons/HostSelector/server.hpp"

#include <error.h>

#include <phosphor-logging/lg2.hpp>
namespace sdbusRule = sdbusplus::bus::match::rules;
// add the button iface class to registry
static ButtonIFRegister<SerialUartMux> buttonRegister;
namespace HostSelectorServerObj =
    sdbusplus::xyz::openbmc_project::Chassis::Buttons::server;
namespace HostSelectorClientObj =
    sdbusplus::xyz::openbmc_project::Chassis::Buttons::client::HostSelector;

constexpr std::string_view SERIAL_UART_RX_GPIO = "serial_uart_rx";
void SerialUartMux::init()
{
    try
    {
        // when Host Selector Position is changed call the handler

        std::string matchPattern = sdbusRule::propertiesChanged(
            HS_DBUS_OBJECT_NAME, HostSelectorClientObj::interface);

        hostPositionChanged = std::make_unique<sdbusplus::bus::match_t>(
            bus, matchPattern,
            std::bind(std::mem_fn(&SerialUartMux::hostSelectorPositionChanged),
                      this, std::placeholders::_1));
    }
    catch (const std::exception& e)
    {
        lg2::error(
            "Failed binding to matching function : {BUTTON_TYPE},Exception : {ERROR}",
            "BUTTON_TYPE", getFormFactorName(), "ERROR", e);
        throw sdbusplus::xyz::openbmc_project::Chassis::Common::Error::
            IOError();
    }
}
// check the debug card present pin
bool SerialUartMux::isOCPDebugCardPresent()
{
    auto gpioState =
        getGpioState(debugCardPresentGpio.fd, debugCardPresentGpio.polarity);
    return (gpioState == GpioState::assert);
}
// set the serial uart MUX to select the console w.r.t host selector position
void SerialUartMux::configSerialConsoleMux(size_t position)
{
    auto debugCardPresent = isOCPDebugCardPresent();

    if (debugCardPresent)
    {
        lg2::info("Debug card is present ");
    }
    else
    {
        lg2::info("Debug card not present ");
    }

    for (size_t uartMuxSel = 0; uartMuxSel < gpioLineCount; uartMuxSel++)
    {
        auto gpioState = GpioState::invalid;
        gpioInfo gpioConfig = config.gpios[uartMuxSel];

        if (gpioConfig.name == SERIAL_UART_RX_GPIO)
        {
            gpioState =
                debugCardPresent ? GpioState::assert : GpioState::deassert;
        }
        else
        {
            gpioState = (serialUartMuxMap[position] & (0x1 << uartMuxSel))
                            ? GpioState::assert
                            : GpioState::deassert;
        }
        setGpioState(gpioConfig.fd, gpioConfig.polarity, gpioState);
    }
}

void SerialUartMux::hostSelectorPositionChanged(sdbusplus::message_t& msg)
{
    std::string interface;
    std::map<std::string,
             HostSelectorServerObj::HostSelector::PropertiesVariant>
        propertiesChanged;
    lg2::info("hostSelectorPositionChanged callback : {BUTTON_TYPE}",
              "BUTTON_TYPE", getFormFactorName());

    try
    {
        msg.read(interface, propertiesChanged);
        for (auto& property : propertiesChanged)
        {
            auto propertyName = property.first;
            if (propertyName == "Position")
            {
                size_t hostPosition = std::get<size_t>(property.second);
                lg2::debug("property changed : {VALUE}", "VALUE", hostPosition);
                configSerialConsoleMux(hostPosition);
                return;
            }
        }
    }
    catch (const std::exception& e)
    {
        lg2::error("exception while reading dbus property : {ERROR}", "ERROR",
                   e.what());
        return;
    }
}
