#include "dbusSensor.hpp"

#include "virtualSensor.hpp"

#include <sdbusplus/bus.hpp>
#include <sdbusplus/bus/match.hpp>

#include <cmath>
static constexpr auto sensorIntf =
    sdbusplus::common::xyz::openbmc_project::sensor::Value::interface;

/** When the Entity Manager removes the sensor, the interfaceRemoveSignal sent
 * uses the path /xyz/openbmc_project/sensors
 * */
static constexpr auto interfacesSensorPath = "/xyz/openbmc_project/sensors";

namespace phosphor::virtual_sensor
{

DbusSensor::DbusSensor(sdbusplus::bus_t& bus, const std::string& path,
                       VirtualSensor& virtualSensor) :
    bus(bus), path(path), virtualSensor(virtualSensor),
    signalPropChange(
        bus, sdbusplus::bus::match::rules::propertiesChanged(path, sensorIntf),
        [this](sdbusplus::message_t& message) {
            handleDbusSignalPropChange(message);
        }),
    signalRemove(
        bus,
        sdbusplus::bus::match::rules::interfacesRemoved(interfacesSensorPath),
        [this](sdbusplus::message_t& message) {
            handleDbusSignalRemove(message);
        })
{
    initSensorValue();
}

double DbusSensor::getSensorValue()
{
    return value;
}

void DbusSensor::initSensorValue()
{
    try
    {
        // If servName is not empty, reduce one DbusCall
        if (servName.empty())
        {
            value = std::numeric_limits<double>::quiet_NaN();
            servName = getService(bus, path, sensorIntf);
        }

        if (!servName.empty())
        {
            signalNameOwnerChanged.reset();
            signalNameOwnerChanged = std::make_unique<sdbusplus::bus::match_t>(
                bus,
                sdbusplus::bus::match::rules::nameOwnerChanged() +
                    sdbusplus::bus::match::rules::arg0namespace(servName),
                [this](sdbusplus::message_t& message) {
                    handleDbusSignalNameOwnerChanged(message);
                });

            value = getDbusProperty<double>(bus, servName, path, sensorIntf,
                                            "Value");
        }
    }
    catch (const std::exception& e)
    {
        value = std::numeric_limits<double>::quiet_NaN();
    }

    return;
}

void DbusSensor::handleDbusSignalNameOwnerChanged(sdbusplus::message_t& msg)
{
    try
    {
        auto [name, oldOwner,
              newOwner] = msg.unpack<std::string, std::string, std::string>();

        if (!oldOwner.empty() && !name.empty())
        {
            if (name == servName)
            {
                // Connection removed

                value = std::numeric_limits<double>::quiet_NaN();
                virtualSensor.updateVirtualSensor();
            }
        }
    }
    catch (const std::exception& e)
    {
        lg2::error("Error in dbusSensor NameOwnerChanged: {PATH}  {ERROR}",
                   "PATH", path, "ERROR", e);
    }
}

void DbusSensor::handleDbusSignalPropChange(sdbusplus::message_t& msg)
{
    try
    {
        using SensorValuePropertiesVariant = sdbusplus::server::xyz::
            openbmc_project::sensor::Value::PropertiesVariant;
        auto [msgIfce, msgData] =
            msg.unpack<std::string,
                       std::map<std::string, SensorValuePropertiesVariant>>();

        std::string path = msg.get_path();

        if (auto itr = msgData.find("Value"); itr != msgData.end())
        {
            value = std::get<double>(itr->second);
            if (!std::isfinite(value))
            {
                value = std::numeric_limits<double>::quiet_NaN();
            }

            virtualSensor.updateVirtualSensor();
        }
    }
    catch (const std::exception& e)
    {
        lg2::error("Error in dbusSensor PropertyChange: {PATH}  {ERROR}",
                   "PATH", path, "ERROR", e);
    }
}

void DbusSensor::handleDbusSignalRemove(sdbusplus::message_t& msg)
{
    try
    {
        auto objPath = msg.unpack<sdbusplus::message::object_path>();

        if (this->path == objPath)
        {
            value = std::numeric_limits<double>::quiet_NaN();
            virtualSensor.updateVirtualSensor();
        }
    }
    catch (const std::exception& e)
    {
        lg2::error("Error in dbusSensor interfaceRemove: {PATH}  {ERROR}",
                   "PATH", path, "ERROR", e);
    }
}

} // namespace phosphor::virtual_sensor
