#pragma once

#include "dbus-sensor_config.h"

#include "NVMeUtil.hpp"
#include "SensorPaths.hpp"
#include "Thresholds.hpp"
#include "Utils.hpp"

#include <phosphor-logging/lg2.hpp>
#include <sdbusplus/asio/object_server.hpp>
#include <sdbusplus/exception.hpp>

#include <limits>
#include <memory>
#include <string>
#include <vector>

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

constexpr size_t sensorFailedPollTimeMs = 5000;

// Enable useful logging with sensor instrumentation
// This is intentionally not DEBUG, avoid clash with usage in .cpp files
constexpr bool enableInstrumentation = false;

constexpr const char* sensorValueInterface = "xyz.openbmc_project.Sensor.Value";
constexpr const char* valueMutabilityInterfaceName =
    "xyz.openbmc_project.Sensor.ValueMutability";
constexpr const char* availableInterfaceName =
    "xyz.openbmc_project.State.Decorator.Availability";
constexpr const char* operationalInterfaceName =
    "xyz.openbmc_project.State.Decorator.OperationalStatus";
constexpr const size_t errorThreshold = 5;

struct SensorInstrumentation
{
    // These are for instrumentation for debugging
    int numCollectsGood = 0;
    int numCollectsMiss = 0;
    int numStreakGreats = 0;
    int numStreakMisses = 0;
    double minCollected = 0.0;
    double maxCollected = 0.0;
};

struct SetSensorError : sdbusplus::exception_t
{
    const char* name() const noexcept override
    {
        return "xyz.openbmc_project.Common.Errors.NotAllowed";
    }
    const char* description() const noexcept override
    {
        return "Not allowed to set property value.";
    }
    int get_errno() const noexcept override
    {
        return EACCES;
    }
};

struct Sensor
{
    Sensor(const std::string& name,
           std::vector<thresholds::Threshold>&& thresholdData,
           const std::string& configurationPath, const std::string& objectType,
           bool isSettable, bool isMutable, const double max, const double min,
           std::shared_ptr<sdbusplus::asio::connection>& conn,
           PowerState readState = PowerState::always) :
        name(sensor_paths::escapePathForDbus(name)),
        configurationPath(configurationPath),
        configInterface(configInterfaceName(objectType)),
        isSensorSettable(isSettable), isValueMutable(isMutable), maxValue(max),
        minValue(min), thresholds(std::move(thresholdData)),
        hysteresisTrigger((max - min) * 0.01),
        hysteresisPublish((max - min) * 0.0001), dbusConnection(conn),
        readState(readState),
        instrumentation(enableInstrumentation
                            ? std::make_unique<SensorInstrumentation>()
                            : nullptr)
    {}
    virtual ~Sensor() = default;
    virtual void checkThresholds() = 0;
    std::string name;
    std::string configurationPath;
    std::string configInterface;
    bool isSensorSettable;

    /* A flag indicates if properties of xyz.openbmc_project.Sensor.Value
     * interface are mutable. If mutable, then
     * xyz.openbmc_project.Sensor.ValueMutability interface will be
     * instantiated.
     */
    bool isValueMutable;
    double maxValue;
    double minValue;
    std::vector<thresholds::Threshold> thresholds;
    std::shared_ptr<sdbusplus::asio::dbus_interface> sensorInterface;
    std::shared_ptr<sdbusplus::asio::dbus_interface> association;
    std::shared_ptr<sdbusplus::asio::dbus_interface> availableInterface;
    std::shared_ptr<sdbusplus::asio::dbus_interface> operationalInterface;
    std::shared_ptr<sdbusplus::asio::dbus_interface> valueMutabilityInterface;
    double value = std::numeric_limits<double>::quiet_NaN();
    double rawValue = std::numeric_limits<double>::quiet_NaN();
    bool overriddenState = false;
    bool internalSet = false;
    double hysteresisTrigger;
    double hysteresisPublish;
    std::shared_ptr<sdbusplus::asio::connection> dbusConnection;
    PowerState readState;
    size_t errCount{0};
    std::unique_ptr<SensorInstrumentation> instrumentation;

    // This member variable provides a hook that can be used to receive
    // notification whenever this Sensor's value is externally set via D-Bus.
    // If interested, assign your own lambda to this variable, during
    // construction of your Sensor subclass. See ExternalSensor for example.
    std::function<void()> externalSetHook;

    using Level = thresholds::Level;
    using Direction = thresholds::Direction;

    std::array<std::shared_ptr<sdbusplus::asio::dbus_interface>,
               thresholds::thresProp.size()>
        thresholdInterfaces;

    std::shared_ptr<sdbusplus::asio::dbus_interface>
        getThresholdInterface(Level lev)
    {
        size_t index = static_cast<size_t>(lev);
        if (index >= thresholdInterfaces.size())
        {
            std::cout << "Unknown threshold level \n";
            return nullptr;
        }
        std::shared_ptr<sdbusplus::asio::dbus_interface> interface =
            thresholdInterfaces[index];
        return interface;
    }

    void updateInstrumentation(double readValue) const
    {
        // Do nothing if this feature is not enabled
        if constexpr (!enableInstrumentation)
        {
            return;
        }
        if (!instrumentation)
        {
            return;
        }

        // Save some typing
        auto& inst = *instrumentation;

        // Show constants if first reading (even if unsuccessful)
        if ((inst.numCollectsGood == 0) && (inst.numCollectsMiss == 0))
        {
            std::cerr << "Sensor " << name << ": Configuration min=" << minValue
                      << ", max=" << maxValue << ", type=" << configInterface
                      << ", path=" << configurationPath << "\n";
        }

        // Sensors can use "nan" to indicate unavailable reading
        if (!std::isfinite(readValue))
        {
            // Only show this if beginning a new streak
            if (inst.numStreakMisses == 0)
            {
                std::cerr << "Sensor " << name
                          << ": Missing reading, Reading counts good="
                          << inst.numCollectsGood
                          << ", miss=" << inst.numCollectsMiss
                          << ", Prior good streak=" << inst.numStreakGreats
                          << "\n";
            }

            inst.numStreakGreats = 0;
            ++(inst.numCollectsMiss);
            ++(inst.numStreakMisses);

            return;
        }

        // Only show this if beginning a new streak and not the first time
        if ((inst.numStreakGreats == 0) && (inst.numCollectsGood != 0))
        {
            std::cerr << "Sensor " << name
                      << ": Recovered reading, Reading counts good="
                      << inst.numCollectsGood
                      << ", miss=" << inst.numCollectsMiss
                      << ", Prior miss streak=" << inst.numStreakMisses << "\n";
        }

        // Initialize min/max if the first successful reading
        if (inst.numCollectsGood == 0)
        {
            std::cerr << "Sensor " << name << ": First reading=" << readValue
                      << "\n";

            inst.minCollected = readValue;
            inst.maxCollected = readValue;
        }

        inst.numStreakMisses = 0;
        ++(inst.numCollectsGood);
        ++(inst.numStreakGreats);

        // Only provide subsequent output if new min/max established
        if (readValue < inst.minCollected)
        {
            std::cerr << "Sensor " << name << ": Lowest reading=" << readValue
                      << "\n";

            inst.minCollected = readValue;
        }

        if (readValue > inst.maxCollected)
        {
            std::cerr << "Sensor " << name << ": Highest reading=" << readValue
                      << "\n";

            inst.maxCollected = readValue;
        }
    }

    int setSensorValue(const double& newValue, double& oldValue)
    {
        if (!internalSet)
        {
            if (insecureSensorOverride == 0 && !isSensorSettable &&
                !getManufacturingMode())
            {
                throw SetSensorError();
            }

            oldValue = newValue;
            overriddenState = true;
            // check thresholds for external set
            value = newValue;
            checkThresholds();

            // Trigger the hook, as an external set has just happened
            if (externalSetHook)
            {
                externalSetHook();
            }
        }
        else if (!overriddenState)
        {
            oldValue = newValue;
        }
        return 1;
    }

    void setInitialProperties(const std::string& unit,
                              const std::string& label = std::string(),
                              size_t thresholdSize = 0)
    {
        if (readState == PowerState::on || readState == PowerState::biosPost ||
            readState == PowerState::chassisOn)
        {
            setupPowerMatch(dbusConnection);
        }

        createAssociation(association, configurationPath);

        sensorInterface->register_property("Unit", unit);
        sensorInterface->register_property("MaxValue", maxValue);
        sensorInterface->register_property("MinValue", minValue);
        sensorInterface->register_property(
            "Value", value, [this](const double& newValue, double& oldValue) {
            return setSensorValue(newValue, oldValue);
        });

        fillMissingThresholds();

        for (auto& threshold : thresholds)
        {
            if (std::isnan(threshold.hysteresis))
            {
                threshold.hysteresis = hysteresisTrigger;
            }

            std::shared_ptr<sdbusplus::asio::dbus_interface> iface =
                getThresholdInterface(threshold.level);

            if (!iface)
            {
                std::cout << "trying to set uninitialized interface\n";
                continue;
            }

            std::string level = propertyLevel(threshold.level,
                                              threshold.direction);
            std::string alarm = propertyAlarm(threshold.level,
                                              threshold.direction);

            if ((level.empty()) || (alarm.empty()))
            {
                continue;
            }
            size_t thresSize = label.empty() ? thresholds.size()
                                             : thresholdSize;
            iface->register_property(
                level, threshold.value,
                [&, label, thresSize](const double& request, double& oldValue) {
                oldValue = request; // todo, just let the config do this?
                threshold.value = request;
                thresholds::persistThreshold(configurationPath, configInterface,
                                             threshold, dbusConnection,
                                             thresSize, label);
                // Invalidate previously remembered value,
                // so new thresholds will be checked during next update,
                // even if sensor reading remains unchanged.
                value = std::numeric_limits<double>::quiet_NaN();

                // Although tempting, don't call checkThresholds() from here
                // directly. Let the regular sensor monitor call the same
                // using updateValue(), which can check conditions like
                // poweron, etc., before raising any event.
                return 1;
            });
            iface->register_property(alarm, false);
        }
        if (!sensorInterface->initialize())
        {
            std::cerr << "error initializing value interface\n";
        }

        for (auto& thresIface : thresholdInterfaces)
        {
            if (thresIface)
            {
                if (!thresIface->initialize(true))
                {
                    std::cerr << "Error initializing threshold interface \n";
                }
            }
        }

        if (isValueMutable)
        {
            valueMutabilityInterface =
                std::make_shared<sdbusplus::asio::dbus_interface>(
                    dbusConnection, sensorInterface->get_object_path(),
                    valueMutabilityInterfaceName);
            valueMutabilityInterface->register_property("Mutable", true);
            if (!valueMutabilityInterface->initialize())
            {
                std::cerr
                    << "error initializing sensor value mutability interface\n";
                valueMutabilityInterface = nullptr;
            }
        }

        if (!availableInterface)
        {
            availableInterface =
                std::make_shared<sdbusplus::asio::dbus_interface>(
                    dbusConnection, sensorInterface->get_object_path(),
                    availableInterfaceName);
            availableInterface->register_property(
                "Available", true, [this](const bool propIn, bool& old) {
                if (propIn == old)
                {
                    return 1;
                }
                old = propIn;
                if (!propIn)
                {
                    updateValue(std::numeric_limits<double>::quiet_NaN());
                }
                return 1;
            });
            availableInterface->initialize();
        }
        if (!operationalInterface)
        {
            operationalInterface =
                std::make_shared<sdbusplus::asio::dbus_interface>(
                    dbusConnection, sensorInterface->get_object_path(),
                    operationalInterfaceName);
            operationalInterface->register_property("Functional", true);
            operationalInterface->initialize();
        }
    }

    static std::string propertyLevel(const Level lev, const Direction dir)
    {
        for (const thresholds::ThresholdDefinition& prop :
             thresholds::thresProp)
        {
            if (prop.level == lev)
            {
                if (dir == Direction::HIGH)
                {
                    return std::string(prop.levelName) + "High";
                }
                if (dir == Direction::LOW)
                {
                    return std::string(prop.levelName) + "Low";
                }
            }
        }
        return "";
    }

    static std::string propertyAlarm(const Level lev, const Direction dir)
    {
        for (const thresholds::ThresholdDefinition& prop :
             thresholds::thresProp)
        {
            if (prop.level == lev)
            {
                if (dir == Direction::HIGH)
                {
                    return std::string(prop.levelName) + "AlarmHigh";
                }
                if (dir == Direction::LOW)
                {
                    return std::string(prop.levelName) + "AlarmLow";
                }
            }
        }
        return "";
    }

    bool readingStateGood() const
    {
        return ::readingStateGood(readState);
    }

    void markFunctional(bool isFunctional)
    {
        if (operationalInterface)
        {
            operationalInterface->set_property("Functional", isFunctional);
        }
        if (isFunctional)
        {
            errCount = 0;
        }
        else
        {
            updateValue(std::numeric_limits<double>::quiet_NaN());
        }
    }

    void markAvailable(bool isAvailable)
    {
        if (availableInterface)
        {
            availableInterface->set_property("Available", isAvailable);
            errCount = 0;
        }
    }

    void incrementError()
    {
        if (!readingStateGood())
        {
            markAvailable(false);
            return;
        }

        if (errCount >= errorThreshold)
        {
            return;
        }

        errCount++;
        if (errCount == errorThreshold)
        {
            std::cerr << "Sensor " << name << " reading error!\n";
            markFunctional(false);
        }
    }

    bool inError() const
    {
        return errCount >= errorThreshold;
    }

    void updateValue(const double& newValue)
    {
        // Ignore if overriding is enabled
        if (overriddenState)
        {
            return;
        }

        if (!readingStateGood())
        {
            markAvailable(false);
            for (auto& threshold : thresholds)
            {
                assertThresholds(this, value, threshold.level,
                                 threshold.direction, false);
            }
            updateValueProperty(std::numeric_limits<double>::quiet_NaN());
            return;
        }

        updateValueProperty(newValue);
        updateInstrumentation(newValue);

        // Always check thresholds after changing the value,
        // as the test against hysteresisTrigger now takes place in
        // the thresholds::checkThresholds() method,
        // which is called by checkThresholds() below,
        // in all current implementations of sensors that have thresholds.
        checkThresholds();
        if (!std::isnan(newValue))
        {
            markFunctional(true);
            markAvailable(true);
        }
    }

    void updateProperty(
        std::shared_ptr<sdbusplus::asio::dbus_interface>& interface,
        double& oldValue, const double& newValue,
        const char* dbusPropertyName) const
    {
        if (requiresUpdate(oldValue, newValue))
        {
            oldValue = newValue;
            if (interface &&
                !(interface->set_property(dbusPropertyName, newValue)))
            {
                std::cerr << "error setting property " << dbusPropertyName
                          << " to " << newValue << "\n";
            }
        }
    }

    bool requiresUpdate(const double& lVal, const double& rVal) const
    {
        const auto lNan = std::isnan(lVal);
        const auto rNan = std::isnan(rVal);
        if (lNan || rNan)
        {
            return (lNan != rNan);
        }
        return std::abs(lVal - rVal) > hysteresisPublish;
    }

  private:
    // If one of the thresholds for a dbus interface is provided
    // we have to set the other one as dbus properties are never
    // optional.
    void fillMissingThresholds()
    {
        for (thresholds::Threshold& thisThreshold : thresholds)
        {
            bool foundOpposite = false;
            thresholds::Direction opposite = thresholds::Direction::HIGH;
            if (thisThreshold.direction == thresholds::Direction::HIGH)
            {
                opposite = thresholds::Direction::LOW;
            }
            for (thresholds::Threshold& otherThreshold : thresholds)
            {
                if (thisThreshold.level != otherThreshold.level)
                {
                    continue;
                }
                if (otherThreshold.direction != opposite)
                {
                    continue;
                }
                foundOpposite = true;
                break;
            }
            if (foundOpposite)
            {
                continue;
            }
            thresholds.emplace_back(thisThreshold.level, opposite,
                                    std::numeric_limits<double>::quiet_NaN());
        }
    }

    void updateValueProperty(const double& newValue)
    {
        // Indicate that it is internal set call, not an external overwrite
        internalSet = true;
        updateProperty(sensorInterface, value, newValue, "Value");
        internalSet = false;

#ifdef NVMED_ENABLE_SHMEM
        milotic_tlbmc::IpcClient* shmClientPtr =
            &milotic_tlbmc::StaticSharedMemoryClient::GetInstance();
        if (shmClientPtr != nullptr)
        {
            std::string sharedMemSensorName = absl::StrCat("sharedmem_",
                                                           this->name);

            absl::Status status =
                shmClientPtr->UpdateSensorValue(sharedMemSensorName, newValue);

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