#include "numeric_sensor.hpp"

#include "common/utils.hpp"
#include "requester/handler.hpp"

#include <libpldm/platform.h>

#include <xyz/openbmc_project/Logging/Entry/client.hpp>

#include <limits>
#include <regex>

#ifdef PLDMD_ENABLE_SHMEM
#include <absl/status/status.h>
#include <absl/strings/str_cat.h>
#include <shared_memory/static_client_impl.h>
#endif

PHOSPHOR_LOG2_USING;

namespace pldm
{
namespace platform_mc
{

// This allows code to cleanly iterate through all supported
// threshold levels and directions.
static const std::array<pldm::utils::Level, 3> allThresholdLevels = {
    pldm::utils::Level::WARNING, pldm::utils::Level::CRITICAL,
    pldm::utils::Level::HARDSHUTDOWN};
static const std::array<pldm::utils::Direction, 2> allThresholdDirections = {
    pldm::utils::Direction::HIGH, pldm::utils::Direction::LOW};

inline bool NumericSensor::createInventoryPath(
    const std::string& associationPath, const std::string& sensorName,
    const uint16_t entityType, const uint16_t entityInstanceNum,
    const uint16_t containerId)
{
    auto& bus = pldm::utils::DBusHandler::getBus();
    std::string invPath = associationPath + "/" + sensorName;
    try
    {
        entityIntf = std::make_unique<EntityIntf>(bus, invPath.c_str());
    }
    catch (const sdbusplus::exception_t& e)
    {
        lg2::error(
            "Failed to create Entity interface for compact numeric sensor {PATH} error - {ERROR}",
            "PATH", invPath, "ERROR", e);
        return false;
    }
    entityIntf->entityType(entityType);
    entityIntf->entityInstanceNumber(entityInstanceNum);
    entityIntf->containerID(containerId);

    return true;
}

inline double getSensorDataValue(uint8_t sensor_data_size,
                                 union_sensor_data_size& value)
{
    double ret = std::numeric_limits<double>::quiet_NaN();
    switch (sensor_data_size)
    {
        case PLDM_SENSOR_DATA_SIZE_UINT8:
            ret = value.value_u8;
            break;
        case PLDM_SENSOR_DATA_SIZE_SINT8:
            ret = value.value_s8;
            break;
        case PLDM_SENSOR_DATA_SIZE_UINT16:
            ret = value.value_u16;
            break;
        case PLDM_SENSOR_DATA_SIZE_SINT16:
            ret = value.value_s16;
            break;
        case PLDM_SENSOR_DATA_SIZE_UINT32:
            ret = value.value_u32;
            break;
        case PLDM_SENSOR_DATA_SIZE_SINT32:
            ret = value.value_s32;
            break;
        case PLDM_SENSOR_DATA_SIZE_UINT64:
            ret = value.value_u64;
            break;
        case PLDM_SENSOR_DATA_SIZE_SINT64:
            ret = value.value_s64;
            break;
    }
    return ret;
}

inline double getRangeFieldValue(uint8_t range_field_format,
                                 union_range_field_format& value)
{
    double ret = std::numeric_limits<double>::quiet_NaN();
    switch (range_field_format)
    {
        case PLDM_RANGE_FIELD_FORMAT_UINT8:
            ret = value.value_u8;
            break;
        case PLDM_RANGE_FIELD_FORMAT_SINT8:
            ret = value.value_s8;
            break;
        case PLDM_RANGE_FIELD_FORMAT_UINT16:
            ret = value.value_u16;
            break;
        case PLDM_RANGE_FIELD_FORMAT_SINT16:
            ret = value.value_s16;
            break;
        case PLDM_RANGE_FIELD_FORMAT_UINT32:
            ret = value.value_u32;
            break;
        case PLDM_RANGE_FIELD_FORMAT_SINT32:
            ret = value.value_s32;
            break;
        case PLDM_RANGE_FIELD_FORMAT_REAL32:
            ret = value.value_f32;
            break;
        case PLDM_RANGE_FIELD_FORMAT_UINT64:
            ret = value.value_u64;
            break;
        case PLDM_RANGE_FIELD_FORMAT_SINT64:
            ret = value.value_s64;
            break;
    }
    return ret;
}

void NumericSensor::setSensorUnit(uint8_t baseUnit)
{
    sensorUnit = SensorUnit::DegreesC;
    useMetricInterface = false;
    switch (baseUnit)
    {
        case PLDM_SENSOR_UNIT_DEGRESS_C:
            sensorNameSpace = "/xyz/openbmc_project/sensors/temperature/";
            sensorUnit = SensorUnit::DegreesC;
            break;
        case PLDM_SENSOR_UNIT_VOLTS:
            sensorNameSpace = "/xyz/openbmc_project/sensors/voltage/";
            sensorUnit = SensorUnit::Volts;
            break;
        case PLDM_SENSOR_UNIT_AMPS:
            sensorNameSpace = "/xyz/openbmc_project/sensors/current/";
            sensorUnit = SensorUnit::Amperes;
            break;
        case PLDM_SENSOR_UNIT_RPM:
            sensorNameSpace = "/xyz/openbmc_project/sensors/fan_pwm/";
            sensorUnit = SensorUnit::RPMS;
            break;
        case PLDM_SENSOR_UNIT_WATTS:
            sensorNameSpace = "/xyz/openbmc_project/sensors/power/";
            sensorUnit = SensorUnit::Watts;
            break;
        case PLDM_SENSOR_UNIT_JOULES:
            sensorNameSpace = "/xyz/openbmc_project/sensors/energy/";
            sensorUnit = SensorUnit::Joules;
            break;
        case PLDM_SENSOR_UNIT_PERCENTAGE:
            sensorNameSpace = "/xyz/openbmc_project/sensors/utilization/";
            sensorUnit = SensorUnit::Percent;
            break;
        case PLDM_SENSOR_UNIT_HERTZ:
            sensorNameSpace = "/xyz/openbmc_project/sensors/frequency/";
            useMetricInterface = true;
            break;
        case PLDM_SENSOR_UNIT_COUNTS:
        case PLDM_SENSOR_UNIT_CORRECTED_ERRORS:
        case PLDM_SENSOR_UNIT_UNCORRECTABLE_ERRORS:
        case PLDM_SENSOR_UNIT_BITS:
            sensorNameSpace = "/xyz/openbmc_project/metric/count/";
            useMetricInterface = true;
            break;
        case PLDM_SENSOR_UNIT_OEMUNIT:
            sensorNameSpace = "/xyz/openbmc_project/metric/oem/";
            useMetricInterface = true;
            break;
        default:
            lg2::error("Sensor {NAME} has Invalid baseUnit {UNIT}.", "NAME",
                       sensorName, "UNIT", baseUnit);
            throw sdbusplus::xyz::openbmc_project::Common::Error::
                InvalidArgument();
            break;
    }
}

NumericSensor::NumericSensor(
    const pldm_tid_t tid, const bool sensorDisabled,
    std::shared_ptr<pldm_numeric_sensor_value_pdr> pdr, std::string& sensorName,
    std::string& associationPath) : tid(tid), sensorName(sensorName)
{
#ifdef PLDMD_ENABLE_SHMEM
    sharedMemSensorName = absl::StrCat("sharedmem_", sensorName);
#endif
    if (!pdr)
    {
        throw sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument();
    }

    sensorId = pdr->sensor_id;
    std::string path;
    MetricUnit metricUnit = MetricUnit::Count;
    setSensorUnit(pdr->base_unit);

    path = sensorNameSpace + sensorName;
    try
    {
        std::string tmp{};
        std::string interface = ValueIntf::interface;
        if (useMetricInterface)
        {
            interface = MetricIntf::interface;
        }
        tmp = pldm::utils::DBusHandler().getService(path.c_str(),
                                                    interface.c_str());

        if (!tmp.empty())
        {
            throw sdbusplus::xyz::openbmc_project::Common::Error::
                TooManyResources();
        }
    }
    catch (const std::exception&)
    {
        /* The sensor object path is not created */
    }

    auto& bus = pldm::utils::DBusHandler::getBus();
    try
    {
        associationDefinitionsIntf =
            std::make_unique<AssociationDefinitionsInft>(bus, path.c_str());
    }
    catch (const sdbusplus::exception_t& e)
    {
        lg2::error(
            "Failed to create association interface for numeric sensor {PATH} error - {ERROR}",
            "PATH", path, "ERROR", e);
        throw sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument();
    }

    if (useMetricInterface)
    {
        associationDefinitionsIntf->associations(
            {{"measuring", "measured_by", associationPath}});
    }
    else
    {
        associationDefinitionsIntf->associations(
            {{"chassis", "all_sensors", associationPath}});
    }

    double maxValue =
        getSensorDataValue(pdr->sensor_data_size, pdr->max_readable);
    double minValue =
        getSensorDataValue(pdr->sensor_data_size, pdr->min_readable);
    hysteresis = getSensorDataValue(pdr->sensor_data_size, pdr->hysteresis);

    bool hasCriticalThresholds = false;
    bool hasWarningThresholds = false;
    bool hasFatalThresholds = false;
    double criticalHigh = std::numeric_limits<double>::quiet_NaN();
    double criticalLow = std::numeric_limits<double>::quiet_NaN();
    double warningHigh = std::numeric_limits<double>::quiet_NaN();
    double warningLow = std::numeric_limits<double>::quiet_NaN();
    double fatalHigh = std::numeric_limits<double>::quiet_NaN();
    double fatalLow = std::numeric_limits<double>::quiet_NaN();

    if (pdr->supported_thresholds.bits.bit0)
    {
        hasWarningThresholds = true;
        warningHigh =
            getRangeFieldValue(pdr->range_field_format, pdr->warning_high);
    }

    if (pdr->supported_thresholds.bits.bit3)
    {
        hasWarningThresholds = true;
        warningLow =
            getRangeFieldValue(pdr->range_field_format, pdr->warning_low);
    }

    if (pdr->supported_thresholds.bits.bit1)
    {
        hasCriticalThresholds = true;
        criticalHigh =
            getRangeFieldValue(pdr->range_field_format, pdr->critical_high);
    }

    if (pdr->supported_thresholds.bits.bit4)
    {
        hasCriticalThresholds = true;
        criticalLow =
            getRangeFieldValue(pdr->range_field_format, pdr->critical_low);
    }
    if (pdr->supported_thresholds.bits.bit2)
    {
        hasFatalThresholds = true;
        fatalHigh =
            getRangeFieldValue(pdr->range_field_format, pdr->fatal_high);
    }
    if (pdr->supported_thresholds.bits.bit5)
    {
        hasFatalThresholds = true;
        fatalLow = getRangeFieldValue(pdr->range_field_format, pdr->fatal_low);
    }

    resolution = pdr->resolution;
    offset = pdr->offset;
    baseUnitModifier = pdr->unit_modifier;
    timeStamp = 0;

    /**
     * DEFAULT_SENSOR_UPDATER_INTERVAL is in milliseconds
     * updateTime is in microseconds
     */
    updateTime = static_cast<uint64_t>(DEFAULT_SENSOR_UPDATER_INTERVAL * 1000);
    if (std::isfinite(pdr->update_interval))
    {
        updateTime = pdr->update_interval * 1000000;
    }

    if (!useMetricInterface)
    {
        try
        {
            valueIntf = std::make_unique<ValueIntf>(bus, path.c_str());
        }
        catch (const sdbusplus::exception_t& e)
        {
            lg2::error(
                "Failed to create Value interface for numeric sensor {PATH} error - {ERROR}",
                "PATH", path, "ERROR", e);
            throw sdbusplus::xyz::openbmc_project::Common::Error::
                InvalidArgument();
        }
        valueIntf->maxValue(unitModifier(conversionFormula(maxValue)));
        valueIntf->minValue(unitModifier(conversionFormula(minValue)));
        valueIntf->unit(sensorUnit);
    }
    else
    {
        try
        {
            metricIntf = std::make_unique<MetricIntf>(bus, path.c_str());
        }
        catch (const sdbusplus::exception_t& e)
        {
            lg2::error(
                "Failed to create Metric interface for numeric sensor {PATH} error - {ERROR}",
                "PATH", path, "ERROR", e);
            throw sdbusplus::xyz::openbmc_project::Common::Error::
                InvalidArgument();
        }
        metricIntf->maxValue(unitModifier(conversionFormula(maxValue)));
        metricIntf->minValue(unitModifier(conversionFormula(minValue)));
        metricIntf->unit(metricUnit);
    }

    hysteresis = unitModifier(conversionFormula(hysteresis));

    if (!createInventoryPath(associationPath, sensorName, pdr->entity_type,
                             pdr->entity_instance_num, pdr->container_id))
    {
        throw sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument();
    }

    try
    {
        availabilityIntf =
            std::make_unique<AvailabilityIntf>(bus, path.c_str());
    }
    catch (const sdbusplus::exception_t& e)
    {
        lg2::error(
            "Failed to create Availability interface for numeric sensor {PATH} error - {ERROR}",
            "PATH", path, "ERROR", e);
        throw sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument();
    }
    availabilityIntf->available(true);

    try
    {
        operationalStatusIntf =
            std::make_unique<OperationalStatusIntf>(bus, path.c_str());
    }
    catch (const sdbusplus::exception_t& e)
    {
        lg2::error(
            "Failed to create Operation status interface for numeric sensor {PATH} error - {ERROR}",
            "PATH", path, "ERROR", e);
        throw sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument();
    }
    operationalStatusIntf->functional(!sensorDisabled);

    if (hasWarningThresholds && !useMetricInterface)
    {
        try
        {
            thresholdWarningIntf =
                std::make_unique<ThresholdWarningIntf>(bus, path.c_str());
        }
        catch (const sdbusplus::exception_t& e)
        {
            lg2::error(
                "Failed to create Threshold warning interface for numeric sensor {PATH} error - {ERROR}",
                "PATH", path, "ERROR", e);
            throw sdbusplus::xyz::openbmc_project::Common::Error::
                InvalidArgument();
        }
        thresholdWarningIntf->warningHigh(unitModifier(warningHigh));
        thresholdWarningIntf->warningLow(unitModifier(warningLow));
    }

    if (hasCriticalThresholds && !useMetricInterface)
    {
        try
        {
            thresholdCriticalIntf =
                std::make_unique<ThresholdCriticalIntf>(bus, path.c_str());
        }
        catch (const sdbusplus::exception_t& e)
        {
            lg2::error(
                "Failed to create Threshold critical interface for numeric sensor {PATH} error - {ERROR}",
                "PATH", path, "ERROR", e);
            throw sdbusplus::xyz::openbmc_project::Common::Error::
                InvalidArgument();
        }
        thresholdCriticalIntf->criticalHigh(unitModifier(criticalHigh));
        thresholdCriticalIntf->criticalLow(unitModifier(criticalLow));
    }

    if (hasFatalThresholds && !useMetricInterface)
    {
        try
        {
            thresholdHardShutdownIntf =
                std::make_unique<ThresholdHardShutdownIntf>(bus, path.c_str());
        }
        catch (const sdbusplus::exception_t& e)
        {
            lg2::error(
                "Failed to create HardShutdown threshold interface for numeric sensor {PATH} error - {ERROR}",
                "PATH", path, "ERROR", e);
            throw sdbusplus::xyz::openbmc_project::Common::Error::
                InvalidArgument();
        }
        thresholdHardShutdownIntf->hardShutdownHigh(unitModifier(fatalHigh));
        thresholdHardShutdownIntf->hardShutdownLow(unitModifier(fatalLow));
    }
}

NumericSensor::NumericSensor(
    const pldm_tid_t tid, const bool sensorDisabled,
    std::shared_ptr<pldm_compact_numeric_sensor_pdr> pdr,
    std::string& sensorName, std::string& associationPath) :
    tid(tid), sensorName(sensorName)
{
#ifdef PLDMD_ENABLE_SHMEM
    sharedMemSensorName = absl::StrCat("sharedmem_", sensorName);
#endif

    if (!pdr)
    {
        throw sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument();
    }

    sensorId = pdr->sensor_id;
    std::string path;
    MetricUnit metricUnit = MetricUnit::Count;
    setSensorUnit(pdr->base_unit);

    path = sensorNameSpace + sensorName;
    try
    {
        std::string tmp{};
        std::string interface = ValueIntf::interface;
        if (useMetricInterface)
        {
            interface = MetricIntf::interface;
        }
        tmp = pldm::utils::DBusHandler().getService(path.c_str(),
                                                    interface.c_str());

        if (!tmp.empty())
        {
            throw sdbusplus::xyz::openbmc_project::Common::Error::
                TooManyResources();
        }
    }
    catch (const std::exception&)
    {
        /* The sensor object path is not created */
    }

    auto& bus = pldm::utils::DBusHandler::getBus();
    try
    {
        associationDefinitionsIntf =
            std::make_unique<AssociationDefinitionsInft>(bus, path.c_str());
    }
    catch (const sdbusplus::exception_t& e)
    {
        lg2::error(
            "Failed to create Association interface for compact numeric sensor {PATH} error - {ERROR}",
            "PATH", path, "ERROR", e);
        throw sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument();
    }
    if (useMetricInterface)
    {
        associationDefinitionsIntf->associations(
            {{"measuring", "measured_by", associationPath.c_str()}});
    }
    else
    {
        associationDefinitionsIntf->associations(
            {{"chassis", "all_sensors", associationPath.c_str()}});
    }

    double maxValue = std::numeric_limits<double>::quiet_NaN();
    double minValue = std::numeric_limits<double>::quiet_NaN();
    bool hasWarningThresholds = false;
    bool hasCriticalThresholds = false;
    bool hasFatalThresholds = false;
    double criticalHigh = std::numeric_limits<double>::quiet_NaN();
    double criticalLow = std::numeric_limits<double>::quiet_NaN();
    double warningHigh = std::numeric_limits<double>::quiet_NaN();
    double warningLow = std::numeric_limits<double>::quiet_NaN();
    double fatalHigh = std::numeric_limits<double>::quiet_NaN();
    double fatalLow = std::numeric_limits<double>::quiet_NaN();

    if (pdr->range_field_support.bits.bit0)
    {
        hasWarningThresholds = true;
        warningHigh = pdr->warning_high;
    }
    if (pdr->range_field_support.bits.bit1)
    {
        hasWarningThresholds = true;
        warningLow = pdr->warning_low;
    }

    if (pdr->range_field_support.bits.bit2)
    {
        hasCriticalThresholds = true;
        criticalHigh = pdr->critical_high;
    }

    if (pdr->range_field_support.bits.bit3)
    {
        hasCriticalThresholds = true;
        criticalLow = pdr->critical_low;
    }
    if (pdr->range_field_support.bits.bit4)
    {
        hasFatalThresholds = true;
        fatalHigh = pdr->fatal_high;
    }
    if (pdr->range_field_support.bits.bit5)
    {
        hasFatalThresholds = true;
        fatalLow = pdr->fatal_low;
    }

    resolution = std::numeric_limits<double>::quiet_NaN();
    offset = std::numeric_limits<double>::quiet_NaN();
    baseUnitModifier = pdr->unit_modifier;
    timeStamp = 0;
    hysteresis = 0;

    /**
     * DEFAULT_SENSOR_UPDATER_INTERVAL is in milliseconds
     * updateTime is in microseconds
     */
    updateTime = static_cast<uint64_t>(DEFAULT_SENSOR_UPDATER_INTERVAL * 1000);

    if (!useMetricInterface)
    {
        try
        {
            valueIntf = std::make_unique<ValueIntf>(bus, path.c_str());
        }
        catch (const sdbusplus::exception_t& e)
        {
            lg2::error(
                "Failed to create Value interface for compact numeric sensor {PATH} error - {ERROR}",
                "PATH", path, "ERROR", e);
            throw sdbusplus::xyz::openbmc_project::Common::Error::
                InvalidArgument();
        }
        valueIntf->maxValue(unitModifier(conversionFormula(maxValue)));
        valueIntf->minValue(unitModifier(conversionFormula(minValue)));
        valueIntf->unit(sensorUnit);
    }
    else
    {
        try
        {
            metricIntf = std::make_unique<MetricIntf>(bus, path.c_str());
        }
        catch (const sdbusplus::exception_t& e)
        {
            lg2::error(
                "Failed to create Metric interface for compact numeric sensor {PATH} error - {ERROR}",
                "PATH", path, "ERROR", e);
            throw sdbusplus::xyz::openbmc_project::Common::Error::
                InvalidArgument();
        }
        metricIntf->maxValue(unitModifier(conversionFormula(maxValue)));
        metricIntf->minValue(unitModifier(conversionFormula(minValue)));
        metricIntf->unit(metricUnit);
    }

    hysteresis = unitModifier(conversionFormula(hysteresis));

    if (!createInventoryPath(associationPath, sensorName, pdr->entity_type,
                             pdr->entity_instance, pdr->container_id))
    {
        throw sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument();
    }

    try
    {
        availabilityIntf =
            std::make_unique<AvailabilityIntf>(bus, path.c_str());
    }
    catch (const sdbusplus::exception_t& e)
    {
        lg2::error(
            "Failed to create Availability interface for compact numeric sensor {PATH} error - {ERROR}",
            "PATH", path, "ERROR", e);
        throw sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument();
    }
    availabilityIntf->available(true);

    try
    {
        operationalStatusIntf =
            std::make_unique<OperationalStatusIntf>(bus, path.c_str());
    }
    catch (const sdbusplus::exception_t& e)
    {
        lg2::error(
            "Failed to create Operational status interface for compact numeric sensor {PATH} error - {ERROR}",
            "PATH", path, "ERROR", e);
        throw sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument();
    }
    operationalStatusIntf->functional(!sensorDisabled);

    if (hasWarningThresholds && !useMetricInterface)
    {
        try
        {
            thresholdWarningIntf =
                std::make_unique<ThresholdWarningIntf>(bus, path.c_str());
        }
        catch (const sdbusplus::exception_t& e)
        {
            lg2::error(
                "Failed to create Warning threshold interface for compact numeric sensor {PATH} error - {ERROR}",
                "PATH", path, "ERROR", e);
            throw sdbusplus::xyz::openbmc_project::Common::Error::
                InvalidArgument();
        }
        thresholdWarningIntf->warningHigh(unitModifier(warningHigh));
        thresholdWarningIntf->warningLow(unitModifier(warningLow));
    }

    if (hasCriticalThresholds && !useMetricInterface)
    {
        try
        {
            thresholdCriticalIntf =
                std::make_unique<ThresholdCriticalIntf>(bus, path.c_str());
        }
        catch (const sdbusplus::exception_t& e)
        {
            lg2::error(
                "Failed to create Critical threshold interface for compact numeric sensor {PATH} error - {ERROR}",
                "PATH", path, "ERROR", e);
            throw sdbusplus::xyz::openbmc_project::Common::Error::
                InvalidArgument();
        }
        thresholdCriticalIntf->criticalHigh(unitModifier(criticalHigh));
        thresholdCriticalIntf->criticalLow(unitModifier(criticalLow));
    }

    if (hasFatalThresholds && !useMetricInterface)
    {
        try
        {
            thresholdHardShutdownIntf =
                std::make_unique<ThresholdHardShutdownIntf>(bus, path.c_str());
        }
        catch (const sdbusplus::exception_t& e)
        {
            lg2::error(
                "Failed to create HardShutdown threshold interface for numeric sensor {PATH} error - {ERROR}",
                "PATH", path, "ERROR", e);
            throw sdbusplus::xyz::openbmc_project::Common::Error::
                InvalidArgument();
        }
        thresholdHardShutdownIntf->hardShutdownHigh(unitModifier(fatalHigh));
        thresholdHardShutdownIntf->hardShutdownLow(unitModifier(fatalLow));
    }
}

double NumericSensor::conversionFormula(double value)
{
    double convertedValue = value;
    if (std::isfinite(resolution))
    {
        convertedValue *= resolution;
    }
    if (std::isfinite(offset))
    {
        convertedValue += offset;
    }
    return convertedValue;
}

double NumericSensor::unitModifier(double value)
{
    if (!std::isfinite(value))
    {
        return value;
    }
    return value * std::pow(10, baseUnitModifier);
}

void NumericSensor::updateReading(bool available, bool functional, double value)
{
    if (!availabilityIntf || !operationalStatusIntf ||
        (!useMetricInterface && !valueIntf) ||
        (useMetricInterface && !metricIntf))
    {
        lg2::error(
            "Failed to update sensor {NAME} D-Bus interface don't exist.",
            "NAME", sensorName);
        return;
    }
    availabilityIntf->available(available);
    operationalStatusIntf->functional(functional);
    double curValue = 0;
    if (!useMetricInterface)
    {
        curValue = valueIntf->value();
    }
    else
    {
        curValue = metricIntf->value();
    }

    double newValue = std::numeric_limits<double>::quiet_NaN();
    if (functional && available)
    {
        newValue = unitModifier(conversionFormula(value));
        if (std::isfinite(newValue) || std::isfinite(curValue))
        {
            if (!useMetricInterface)
            {
                valueIntf->value(newValue);
                updateThresholds();
            }
            else
            {
                metricIntf->value(newValue);
            }
        }
    }
    else
    {
        if (newValue != curValue &&
            (std::isfinite(newValue) || std::isfinite(curValue)))
        {
            if (!useMetricInterface)
            {
                valueIntf->value(std::numeric_limits<double>::quiet_NaN());
            }
            else
            {
                metricIntf->value(std::numeric_limits<double>::quiet_NaN());
            }
        }
    }

#ifdef PLDMD_ENABLE_SHMEM
    updateSharedMemory(newValue);
#endif
}

void NumericSensor::handleErrGetSensorReading()
{
    if (!operationalStatusIntf || (!useMetricInterface && !valueIntf) ||
        (useMetricInterface && !metricIntf))
    {
        lg2::error(
            "Failed to update sensor {NAME} D-Bus interfaces don't exist.",
            "NAME", sensorName);
        return;
    }
    operationalStatusIntf->functional(false);
    if (!useMetricInterface)
    {
        valueIntf->value(std::numeric_limits<double>::quiet_NaN());
    }
    else
    {
        metricIntf->value(std::numeric_limits<double>::quiet_NaN());
    }

#ifdef PLDMD_ENABLE_SHMEM
    updateSharedMemory(std::numeric_limits<double>::quiet_NaN());
#endif
}

#ifdef PLDMD_ENABLE_SHMEM
void NumericSensor::updateSharedMemory(double value)
{
    milotic_tlbmc::IpcClient* shmClientPtr =
        &milotic_tlbmc::StaticSharedMemoryClient::GetInstance();
    if (shmClientPtr != nullptr)
    {
        if (!shmClientPtr->IsSensorSupported(sharedMemSensorName))
        {
            return;
        }
        absl::Status status =
            shmClientPtr->UpdateSensorValue(sharedMemSensorName, value);

        if (!status.ok())
        {
            lg2::error(
                "Failed to publish sensor value to shared memory for {SENSOR_NAME}: {STATUS}",
                "SENSOR_NAME", sharedMemSensorName, "STATUS",
                status.ToString());
        }
    }
    else
    {
        lg2::error("shmClientPtr is null, cannot update shared memory");
    }
}
#endif

bool NumericSensor::checkThreshold(bool alarm, bool direction, double value,
                                   double threshold, double hyst)
{
    if (direction)
    {
        if (value >= threshold)
        {
            return true;
        }
        if (value < (threshold - hyst))
        {
            return false;
        }
    }
    else
    {
        if (value <= threshold)
        {
            return true;
        }
        if (value > (threshold + hyst))
        {
            return false;
        }
    }
    return alarm;
}

bool NumericSensor::hasThresholdAlarm()
{
    bool alarm = false;
    for (auto level : allThresholdLevels)
    {
        for (auto direction : allThresholdDirections)
        {
            alarm |= getThresholdAlarm(level, direction);
        }
    }
    return alarm;
}

void NumericSensor::setWarningThresholdAlarm(pldm::utils::Direction direction,
                                             double value, bool newAlarm)
{
    if (direction == pldm::utils::Direction::HIGH)
    {
        thresholdWarningIntf->warningAlarmHigh(newAlarm);
        if (newAlarm)
        {
            thresholdWarningIntf->warningHighAlarmAsserted(value);
        }
        else
        {
            thresholdWarningIntf->warningHighAlarmDeasserted(value);
        }
    }
    else
    {
        thresholdWarningIntf->warningAlarmLow(newAlarm);
        if (newAlarm)
        {
            thresholdWarningIntf->warningLowAlarmAsserted(value);
        }
        else
        {
            thresholdWarningIntf->warningLowAlarmDeasserted(value);
        }
    }
}

void NumericSensor::setCriticalThresholdAlarm(pldm::utils::Direction direction,
                                              double value, bool newAlarm)
{
    if (direction == pldm::utils::Direction::HIGH)
    {
        thresholdCriticalIntf->criticalAlarmHigh(newAlarm);
        if (newAlarm)
        {
            thresholdCriticalIntf->criticalHighAlarmAsserted(value);
        }
        else
        {
            thresholdCriticalIntf->criticalHighAlarmDeasserted(value);
        }
    }
    else
    {
        thresholdCriticalIntf->criticalAlarmLow(newAlarm);
        if (newAlarm)
        {
            thresholdCriticalIntf->criticalLowAlarmAsserted(value);
        }
        else
        {
            thresholdCriticalIntf->criticalLowAlarmDeasserted(value);
        }
    }
}

void NumericSensor::setHardShutdownThresholdAlarm(
    pldm::utils::Direction direction, double value, bool newAlarm)
{
    if (direction == pldm::utils::Direction::HIGH)
    {
        thresholdHardShutdownIntf->hardShutdownAlarmHigh(newAlarm);
        if (newAlarm)
        {
            thresholdHardShutdownIntf->hardShutdownHighAlarmAsserted(value);
        }
        else
        {
            thresholdHardShutdownIntf->hardShutdownHighAlarmDeasserted(value);
        }
    }
    else
    {
        thresholdHardShutdownIntf->hardShutdownAlarmLow(newAlarm);
        if (newAlarm)
        {
            thresholdHardShutdownIntf->hardShutdownLowAlarmAsserted(value);
        }
        else
        {
            thresholdHardShutdownIntf->hardShutdownLowAlarmDeasserted(value);
        }
    }
}

int NumericSensor::setThresholdAlarm(pldm::utils::Level level,
                                     pldm::utils::Direction direction,
                                     double value, bool newAlarm)
{
    if (!isThresholdValid(level, direction))
    {
        lg2::error(
            "Error:Trigger sensor warning event for non warning threshold sensors {NAME}",
            "NAME", sensorName);
        return PLDM_ERROR;
    }
    auto alarm = getThresholdAlarm(level, direction);
    if (alarm == newAlarm)
    {
        return PLDM_SUCCESS;
    }
    switch (level)
    {
        case pldm::utils::Level::WARNING:
            setWarningThresholdAlarm(direction, value, newAlarm);
            break;
        case pldm::utils::Level::CRITICAL:
            setCriticalThresholdAlarm(direction, value, newAlarm);
            break;
        case pldm::utils::Level::HARDSHUTDOWN:
            setHardShutdownThresholdAlarm(direction, value, newAlarm);
            break;
        default:
            return PLDM_ERROR;
    }
    if (newAlarm)
    {
        createThresholdLog(level, direction, value);
    }
    else
    {
        auto& log = assertedLog[{level, direction}];
        if (log.has_value())
        {
            clearThresholdLog(log);
        }
        // If all alarms have cleared. Log normal range.
        if (!hasThresholdAlarm())
        {
            createNormalRangeLog(value);
        }
    }
    return PLDM_SUCCESS;
}

void NumericSensor::clearThresholdLog(
    std::optional<sdbusplus::message::object_path>& log)
{
    log.reset();
}

/** @brief helper function template to create a threshold log
 *
 * @tparam[in] errorObj - The error object of the log we want to create.
 * @param[in] sensorObjPath - The object path of the sensor.
 * @param[in] value - The current value of the sensor.
 * @param[in] sensorUnit - The units of the sensor.
 * @param[in] threshold - The threshold value.
 *
 * @return optional object holding the object path of the created
 * log entry. If the log entry is being filtered, we would return
 * a optional holding an empty string in the object path. This ensures
 * we follow our state machine properly even if the log is being filtered.
 */
void NumericSensor::createThresholdLog(
    pldm::utils::Level level, pldm::utils::Direction direction, double value)
{
    (void)level;
    (void)direction;
    (void)value;
}

void NumericSensor::createNormalRangeLog(double value)
{
    std::string objPath = sensorNameSpace + sensorName;
    lg2::info("Sensor {OBJPATH} reading returned to normal range: {VALUE}",
              "OBJPATH", objPath, "VALUE", value);
}

void NumericSensor::updateThresholds()
{
    double value = std::numeric_limits<double>::quiet_NaN();

    if ((!useMetricInterface && !valueIntf) ||
        (useMetricInterface && !metricIntf))
    {
        lg2::error(
            "Failed to update thresholds sensor {NAME} D-Bus interfaces don't exist.",
            "NAME", sensorName);
        return;
    }
    if (!useMetricInterface)
    {
        value = valueIntf->value();
    }
    else
    {
        value = metricIntf->value();
    }

    for (auto level : allThresholdLevels)
    {
        for (auto direction : allThresholdDirections)
        {
            auto threshold = getThreshold(level, direction);
            if (!std::isfinite(threshold))
            {
                continue;
            }
            auto alarm = getThresholdAlarm(level, direction);
            auto newAlarm =
                checkThreshold(alarm, direction == pldm::utils::Direction::HIGH,
                               value, threshold, hysteresis);
            setThresholdAlarm(level, direction, value, newAlarm);
        }
    }
}

int NumericSensor::triggerThresholdEvent(
    pldm::utils::Level eventType, pldm::utils::Direction direction,
    double rawValue, bool newAlarm, bool assert)
{
    if (!valueIntf)
    {
        lg2::error(
            "Failed to update thresholds sensor {NAME} D-Bus interfaces don't exist.",
            "NAME", sensorName);
        return PLDM_ERROR;
    }

    auto value = unitModifier(conversionFormula(rawValue));
    lg2::error(
        "triggerThresholdEvent eventType {TID}, direction {SID} value {VAL} newAlarm {PSTATE} assert {ESTATE}",
        "TID", eventType, "SID", direction, "VAL", value, "PSTATE", newAlarm,
        "ESTATE", assert);

    return setThresholdAlarm(eventType, direction, value, newAlarm);
}
} // namespace platform_mc
} // namespace pldm
