#pragma once

#include "dbus-sensor_config.h"

#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)),
        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 = (maxValue - minValue) * 0.01;
    double hysteresisPublish = (maxValue - minValue) * 0.0001;
    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
    }
};
