#include "ExternalSensor.hpp"
#include "Thresholds.hpp"
#include "Utils.hpp"
#include "VariantVisitors.hpp"

#include <boost/asio/error.hpp>
#include <boost/asio/io_context.hpp>
#include <boost/asio/post.hpp>
#include <boost/asio/steady_timer.hpp>
#include <boost/container/flat_map.hpp>
#include <boost/container/flat_set.hpp>
#include <phosphor-logging/lg2.hpp>
#include <sdbusplus/asio/connection.hpp>
#include <sdbusplus/asio/object_server.hpp>
#include <sdbusplus/bus/match.hpp>
#include <sdbusplus/message.hpp>
#include <sdbusplus/message/native_types.hpp>

#include <algorithm>
#include <array>
#include <chrono>
#include <cmath>
#include <functional>
#include <memory>
#include <string>
#include <utility>
#include <variant>
#include <vector>

// Copied from HwmonTempSensor and inspired by
// https://gerrit.openbmc-project.xyz/c/openbmc/dbus-sensors/+/35476

// The ExternalSensor is a sensor whose value is intended to be writable
// by something external to the BMC, so that the host (or something else)
// can write to it, perhaps by using an IPMI or Redfish connection.

// Unlike most other sensors, an external sensor does not correspond
// to a hwmon file or any other kernel/hardware interface,
// so, after initialization, this module does not have much to do,
// but it handles reinitialization and thresholds, similar to the others.
// The main work of this module is to provide backing storage for a
// sensor that exists only virtually, and to provide an optional
// timeout service for detecting loss of timely updates.

// As there is no corresponding driver or hardware to support,
// all configuration of this sensor comes from the JSON parameters:
// MinValue, MaxValue, Timeout, PowerState, Units, Name

// The purpose of "Units" is to specify the physical characteristic
// the external sensor is measuring, because with an external sensor
// there is no other way to tell, and it will be used for the object path
// here: /xyz/openbmc_project/sensors/<Units>/<Name>

// For more information, see external-sensor.md design document:
// https://gerrit.openbmc-project.xyz/c/openbmc/docs/+/41452
// https://github.com/openbmc/docs/tree/master/designs/

static constexpr bool debug = false;

static const char* sensorType = "ExternalSensor";

void updateReaper(
    boost::container::flat_map<std::string, std::shared_ptr<ExternalSensor>>&
        sensors,
    boost::asio::steady_timer& timer,
    const std::chrono::steady_clock::time_point& now)
{
    // First pass, reap all stale sensors
    for (const auto& [name, sensor] : sensors)
    {
        if (!sensor)
        {
            continue;
        }

        if (!sensor->isAliveAndPerishable())
        {
            continue;
        }

        if (!sensor->isAliveAndFresh(now))
        {
            // Mark sensor as dead, no longer alive
            sensor->writeInvalidate();
        }
    }

    std::chrono::steady_clock::duration nextCheck;
    bool needCheck = false;

    // Second pass, determine timer interval to next check
    for (const auto& [name, sensor] : sensors)
    {
        if (!sensor)
        {
            continue;
        }

        if (!sensor->isAliveAndPerishable())
        {
            continue;
        }

        auto expiration = sensor->ageRemaining(now);

        if (needCheck)
        {
            nextCheck = std::min(nextCheck, expiration);
        }
        else
        {
            // Initialization
            nextCheck = expiration;
            needCheck = true;
        }
    }

    if (!needCheck)
    {
        if constexpr (debug)
        {
            lg2::error("Next ExternalSensor timer idle");
        }

        return;
    }

    timer.expires_at(now + nextCheck);

    timer.async_wait([&sensors, &timer](const boost::system::error_code& err) {
        if (err != boost::system::errc::success)
        {
            // Cancellation is normal, as timer is dynamically rescheduled
            if (err != boost::asio::error::operation_aborted)
            {
                lg2::error(
                    "ExternalSensor timer scheduling problem: {ERROR_MESSAGE}",
                    "ERROR_MESSAGE", err.message());
            }
            return;
        }

        updateReaper(sensors, timer, std::chrono::steady_clock::now());
    });

    if constexpr (debug)
    {
        lg2::error(
            "Next ExternalSensor timer '{VALUE}' us", "VALUE",
            std::chrono::duration_cast<std::chrono::microseconds>(nextCheck)
                .count());
    }
}

void createSensors(
    sdbusplus::asio::object_server& objectServer,
    boost::container::flat_map<std::string, std::shared_ptr<ExternalSensor>>&
        sensors,
    std::shared_ptr<sdbusplus::asio::connection>& dbusConnection,
    const std::shared_ptr<boost::container::flat_set<std::string>>&
        sensorsChanged,
    boost::asio::steady_timer& reaperTimer)
{
    if constexpr (debug)
    {
        lg2::error("ExternalSensor considering creating sensors");
    }

    auto getter = std::make_shared<GetSensorConfiguration>(
        dbusConnection,
        [&objectServer, &sensors, &dbusConnection, sensorsChanged,
         &reaperTimer](const ManagedObjectType& sensorConfigurations) {
            bool firstScan = (sensorsChanged == nullptr);

            for (const std::pair<sdbusplus::message::object_path, SensorData>&
                     sensor : sensorConfigurations)
            {
                const std::string& interfacePath = sensor.first.str;
                const SensorData& sensorData = sensor.second;

                auto sensorBase =
                    sensorData.find(configInterfaceName(sensorType));
                if (sensorBase == sensorData.end())
                {
                    lg2::error("Base configuration not found for '{PATH}'",
                               "PATH", interfacePath);
                    continue;
                }

                const SensorBaseConfiguration& baseConfiguration = *sensorBase;
                const SensorBaseConfigMap& baseConfigMap =
                    baseConfiguration.second;

                // MinValue and MinValue are mandatory numeric parameters
                auto minFound = baseConfigMap.find("MinValue");
                if (minFound == baseConfigMap.end())
                {
                    lg2::error("MinValue parameter not found for '{PATH}'",
                               "PATH", interfacePath);
                    continue;
                }
                double minValue =
                    std::visit(VariantToDoubleVisitor(), minFound->second);
                if (!std::isfinite(minValue))
                {
                    lg2::error("MinValue parameter not parsed for '{PATH}'",
                               "PATH", interfacePath);
                    continue;
                }

                auto maxFound = baseConfigMap.find("MaxValue");
                if (maxFound == baseConfigMap.end())
                {
                    lg2::error("MaxValue parameter not found for '{PATH}'",
                               "PATH", interfacePath);
                    continue;
                }
                double maxValue =
                    std::visit(VariantToDoubleVisitor(), maxFound->second);
                if (!std::isfinite(maxValue))
                {
                    lg2::error("MaxValue parameter not parsed for '{PATH}'",
                               "PATH", interfacePath);
                    continue;
                }

                double timeoutSecs = 0.0;

                // Timeout is an optional numeric parameter
                auto timeoutFound = baseConfigMap.find("Timeout");
                if (timeoutFound != baseConfigMap.end())
                {
                    timeoutSecs = std::visit(VariantToDoubleVisitor(),
                                             timeoutFound->second);
                }
                if (!std::isfinite(timeoutSecs) || (timeoutSecs < 0.0))
                {
                    lg2::error("Timeout parameter not parsed for '{PATH}'",
                               "PATH", interfacePath);
                    continue;
                }

                std::string sensorName;
                std::string sensorUnits;

                // Name and Units are mandatory string parameters
                auto nameFound = baseConfigMap.find("Name");
                if (nameFound == baseConfigMap.end())
                {
                    lg2::error("Name parameter not found for '{PATH}'", "PATH",
                               interfacePath);
                    continue;
                }
                sensorName =
                    std::visit(VariantToStringVisitor(), nameFound->second);
                if (sensorName.empty())
                {
                    lg2::error("Name parameter not parsed for '{PATH}'", "PATH",
                               interfacePath);
                    continue;
                }

                auto unitsFound = baseConfigMap.find("Units");
                if (unitsFound == baseConfigMap.end())
                {
                    lg2::error("Units parameter not found for '{PATH}'", "PATH",
                               interfacePath);
                    continue;
                }
                sensorUnits =
                    std::visit(VariantToStringVisitor(), unitsFound->second);
                if (sensorUnits.empty())
                {
                    lg2::error("Units parameter not parsed for '{PATH}'",
                               "PATH", interfacePath);
                    continue;
                }

                // on rescans, only update sensors we were signaled by
                auto findSensor = sensors.find(sensorName);
                if (!firstScan && (findSensor != sensors.end()))
                {
                    std::string suffixName = "/";
                    suffixName += findSensor->second->name;
                    bool found = false;
                    for (auto it = sensorsChanged->begin();
                         it != sensorsChanged->end(); it++)
                    {
                        std::string suffixIt = "/";
                        suffixIt += *it;
                        if (suffixIt.ends_with(suffixName))
                        {
                            sensorsChanged->erase(it);
                            findSensor->second = nullptr;
                            found = true;
                            if constexpr (debug)
                            {
                                lg2::error(
                                    "ExternalSensor '{NAME}' change found",
                                    "NAME", sensorName);
                            }
                            break;
                        }
                    }
                    if (!found)
                    {
                        continue;
                    }
                }

                std::vector<thresholds::Threshold> sensorThresholds;
                if (!parseThresholdsFromConfig(sensorData, sensorThresholds))
                {
                    lg2::error("error populating thresholds for '{NAME}'",
                               "NAME", sensorName);
                }

                PowerState readState = getPowerState(baseConfigMap);

                auto& sensorEntry = sensors[sensorName];
                sensorEntry = nullptr;

                sensorEntry = std::make_shared<ExternalSensor>(
                    sensorType, objectServer, dbusConnection, sensorName,
                    sensorUnits, std::move(sensorThresholds), interfacePath,
                    maxValue, minValue, timeoutSecs, readState);
                sensorEntry->initWriteHook(
                    [&sensors, &reaperTimer](
                        const std::chrono::steady_clock::time_point& now) {
                        updateReaper(sensors, reaperTimer, now);
                    });

                if constexpr (debug)
                {
                    lg2::error("ExternalSensor '{NAME}' created", "NAME",
                               sensorName);
                }
            }
        });

    getter->getConfiguration(std::vector<std::string>{sensorType});
}

int main()
{
    if constexpr (debug)
    {
        lg2::error("ExternalSensor service starting up");
    }

    boost::asio::io_context io;
    auto systemBus = std::make_shared<sdbusplus::asio::connection>(io);
    sdbusplus::asio::object_server objectServer(systemBus, true);

    objectServer.add_manager("/xyz/openbmc_project/sensors");
    systemBus->request_name("xyz.openbmc_project.ExternalSensor");

    boost::container::flat_map<std::string, std::shared_ptr<ExternalSensor>>
        sensors;
    auto sensorsChanged =
        std::make_shared<boost::container::flat_set<std::string>>();
    boost::asio::steady_timer reaperTimer(io);

    boost::asio::post(io, [&objectServer, &sensors, &systemBus,
                           &reaperTimer]() {
        createSensors(objectServer, sensors, systemBus, nullptr, reaperTimer);
    });

    boost::asio::steady_timer filterTimer(io);
    std::function<void(sdbusplus::message_t&)> eventHandler =
        [&objectServer, &sensors, &systemBus, &sensorsChanged, &filterTimer,
         &reaperTimer](sdbusplus::message_t& message) mutable {
            if (message.is_method_error())
            {
                lg2::error("callback method error");
                return;
            }

            const auto* messagePath = message.get_path();
            sensorsChanged->insert(messagePath);
            if constexpr (debug)
            {
                lg2::error("ExternalSensor change event received: '{PATH}'",
                           "PATH", messagePath);
            }

            // this implicitly cancels the timer
            filterTimer.expires_after(std::chrono::seconds(1));

            filterTimer.async_wait(
                [&objectServer, &sensors, &systemBus, &sensorsChanged,
                 &reaperTimer](const boost::system::error_code& ec) mutable {
                    if (ec != boost::system::errc::success)
                    {
                        if (ec != boost::asio::error::operation_aborted)
                        {
                            lg2::error("callback error: '{ERROR_MESSAGE}'",
                                       "ERROR_MESSAGE", ec.message());
                        }
                        return;
                    }

                    createSensors(objectServer, sensors, systemBus,
                                  sensorsChanged, reaperTimer);
                });
        };

    std::vector<std::unique_ptr<sdbusplus::bus::match_t>> matches =
        setupPropertiesChangedMatches(
            *systemBus, std::to_array<const char*>({sensorType}), eventHandler);

    if constexpr (debug)
    {
        lg2::error("ExternalSensor service entering main loop");
    }

    io.run();
}
