#include "dbusSensor.hpp"
#include "exprtkTools.hpp"
#include "thresholds.hpp"

#include <nlohmann/json.hpp>
#include <phosphor-logging/lg2.hpp>
#include <sdbusplus/bus.hpp>
#include <xyz/openbmc_project/Association/Definitions/server.hpp>
#include <xyz/openbmc_project/Sensor/Value/server.hpp>

#include <map>
#include <string>

namespace phosphor
{
namespace virtualSensor
{

PHOSPHOR_LOG2_USING_WITH_FLAGS;

using BasicVariantType =
    std::variant<std::string, int64_t, uint64_t, double, int32_t, uint32_t,
                 int16_t, uint16_t, uint8_t, bool, std::vector<std::string>>;

using PropertyMap = std::map<std::string, BasicVariantType>;

using InterfaceMap = std::map<std::string, PropertyMap>;

using ManagedObjectType =
    std::map<sdbusplus::message::object_path, InterfaceMap>;

using Json = nlohmann::json;

template <typename... T>
using ServerObject = typename sdbusplus::server::object_t<T...>;

using ValueIface = sdbusplus::xyz::openbmc_project::Sensor::server::Value;
using ValueObject = ServerObject<ValueIface>;

using AssociationIface =
    sdbusplus::xyz::openbmc_project::Association::server::Definitions;
using AssociationObject = ServerObject<AssociationIface>;

class SensorParam
{
  public:
    SensorParam() = delete;
    virtual ~SensorParam() = default;

    enum ParamType
    {
        constParam,
        dbusParam
    };

    /** @brief Constructs SensorParam (type = constParam)
     *
     * @param[in] value - Value of constant parameter
     */
    explicit SensorParam(double value) : value(value), paramType(constParam)
    {}

    /** @brief Constructs SensorParam (type = dbusParam)
     *
     * @param[in] bus     - Handle to system dbus
     * @param[in] path    - The Dbus path of sensor
     * @param[in] ctx     - sensor context for update
     */
    SensorParam(sdbusplus::bus_t& bus, const std::string& path, void* ctx) :
        dbusSensor(std::make_unique<DbusSensor>(bus, path, ctx)),
        paramType(dbusParam)
    {}

    /** @brief Get sensor value property from D-bus interface */
    double getParamValue();

  private:
    std::unique_ptr<DbusSensor> dbusSensor = nullptr;
    double value = 0;
    ParamType paramType;
};

class VirtualSensor : public ValueObject
{
  public:
    VirtualSensor() = delete;
    virtual ~VirtualSensor() = default;

    /** @brief Constructs VirtualSensor
     *
     * @param[in] bus          - Handle to system dbus
     * @param[in] objPath      - The Dbus path of sensor
     * @param[in] sensorConfig - Json object for sensor config
     */
    VirtualSensor(sdbusplus::bus_t& bus, const char* objPath,
                  const Json& sensorConfig, const std::string& name) :
        ValueObject(bus, objPath, action::defer_emit),
        bus(bus), name(name)
    {
        initVirtualSensor(sensorConfig, objPath);
    }

    /** @brief Constructs VirtualSensor
     *
     * @param[in] bus          - Handle to system dbus
     * @param[in] objPath      - The Dbus path of sensor
     * @param[in] ifacemap     - All the sensor information
     * @param[in] name         - Virtual sensor name
     * @param[in] type         - Virtual sensor type/unit
     * @param[in] calcType     - Calculation used to calculate sensor value
     * @param[in] entityPath   - Virtual sensor path in entityManager Dbus
     *
     */
    VirtualSensor(sdbusplus::bus_t& bus, const char* objPath,
                  const InterfaceMap& ifacemap, const std::string& name,
                  const std::string& type, const std::string& calculationType,
                  const std::string& entityPath) :
        ValueObject(bus, objPath, action::defer_emit),
        bus(bus), name(name), entityPath(entityPath)
    {
        initVirtualSensor(ifacemap, objPath, type, calculationType);
    }

    /** @brief Set sensor value */
    void setSensorValue(double value);
    /** @brief Update sensor at regular intrval */
    void updateVirtualSensor();
    /** @brief Check if sensor value is in valid range */
    bool sensorInRange(double value);

    /** @brief Map of list of parameters */
    using ParamMap =
        std::unordered_map<std::string, std::unique_ptr<SensorParam>>;
    ParamMap paramMap;

  private:
    /** @brief sdbusplus bus client connection. */
    sdbusplus::bus_t& bus;
    /** @brief name of sensor */
    std::string name;

    /** @brief Virtual sensor path in entityManager Dbus.
     * This value is used to set thresholds/create association
     */
    std::string entityPath;
    /** @brief Expression string for virtual sensor value calculations */
    std::string exprStr;
    /** @brief symbol table from exprtk */
    exprtk::symbol_table<double> symbols{};
    /** @brief expression from exprtk to calculate sensor value */
    exprtk::expression<double> expression{};
    /** @brief The vecops package so the expression can use vectors */
    exprtk::rtl::vecops::package<double> vecopsPackage;
    /** @brief The maximum valid value for an input sensor **/
    double maxValidInput = std::numeric_limits<double>::infinity();
    /** @brief The minimum valid value for an input sensor **/
    double minValidInput = -std::numeric_limits<double>::infinity();

    /** @brief The critical threshold interface object */
    std::unique_ptr<Threshold<CriticalObject>> criticalIface;
    /** @brief The warning threshold interface object */
    std::unique_ptr<Threshold<WarningObject>> warningIface;
    /** @brief The soft shutdown threshold interface object */
    std::unique_ptr<Threshold<SoftShutdownObject>> softShutdownIface;
    /** @brief The hard shutdown threshold interface object */
    std::unique_ptr<Threshold<HardShutdownObject>> hardShutdownIface;
    /** @brief The performance loss threshold interface object */
    std::unique_ptr<Threshold<PerformanceLossObject>> perfLossIface;

    /** @brief The association interface object */
    std::unique_ptr<AssociationObject> associationIface;

    /** @brief Read config from json object and initialize sensor data
     * for each virtual sensor
     */
    void initVirtualSensor(const Json& sensorConfig,
                           const std::string& objPath);

    /** @brief Read config from interface map and initialize sensor data
     * for each virtual sensor
     */
    void initVirtualSensor(const InterfaceMap& interfaceMap,
                           const std::string& objPath,
                           const std::string& sensorType,
                           const std::string& calculationType);

    /** @brief Returns which calculation function or expression to use */
    double calculateValue(const std::string& sensortype,
                          const VirtualSensor::ParamMap& paramMap);
    /** @brief Calculate median value from sensors */
    double
        calculateModifiedMedianValue(const VirtualSensor::ParamMap& paramMap);
    /** @brief create threshold objects from json config */
    void createThresholds(const Json& threshold, const std::string& objPath);
    /** @brief parse config from entity manager **/
    void parseConfigInterface(const PropertyMap& propertyMap,
                              const std::string& sensorType,
                              const std::string& interface);

    /** @brief Check Sensor threshold and update alarm and log */
    template <typename V, typename T>
    void checkThresholds(V value, T& threshold)
    {
        if (!threshold)
            return;

        static constexpr auto tname = T::element_type::name;

        auto alarmHigh = threshold->alarmHigh();
        auto highHysteresis = threshold->getHighHysteresis();
        if ((!alarmHigh && value >= threshold->high()) ||
            (alarmHigh && value < (threshold->high() - highHysteresis)))
        {
            if (!alarmHigh)
            {
                error("ASSERT: sensor {SENSOR} is above the upper threshold "
                      "{THRESHOLD}.",
                      "SENSOR", name, "THRESHOLD", tname);
                threshold->alarmHighSignalAsserted(value);
            }
            else
            {
                info("DEASSERT: sensor {SENSOR} is under the upper threshold "
                     "{THRESHOLD}.",
                     "SENSOR", name, "THRESHOLD", tname);
                threshold->alarmHighSignalDeasserted(value);
            }
            threshold->alarmHigh(!alarmHigh);
        }

        auto alarmLow = threshold->alarmLow();
        auto lowHysteresis = threshold->getLowHysteresis();
        if ((!alarmLow && value <= threshold->low()) ||
            (alarmLow && value > (threshold->low() + lowHysteresis)))
        {
            if (!alarmLow)
            {
                error("ASSERT: sensor {SENSOR} is below the lower threshold "
                      "{THRESHOLD}.",
                      "SENSOR", name, "THRESHOLD", tname);
                threshold->alarmLowSignalAsserted(value);
            }
            else
            {
                info("DEASSERT: sensor {SENSOR} is above the lower threshold "
                     "{THRESHOLD}.",
                     "SENSOR", name, "THRESHOLD", tname);
                threshold->alarmLowSignalDeasserted(value);
            }
            threshold->alarmLow(!alarmLow);
        }
    }

    /** @brief Create Association from entityPath*/
    void createAssociation(const std::string& objPath,
                           const std::string& entityPath);
};

class VirtualSensors
{
  public:
    VirtualSensors() = delete;
    virtual ~VirtualSensors() = default;

    /** @brief Constructs VirtualSensors
     *
     * @param[in] bus     - Handle to system dbus
     */
    explicit VirtualSensors(sdbusplus::bus_t& bus) : bus(bus)
    {
        createVirtualSensors();
    }
    /** @brief Calls createVirtualSensor when interface added */
    void propertiesChanged(sdbusplus::message_t& msg);

  private:
    /** @brief sdbusplus bus client connection. */
    sdbusplus::bus_t& bus;
    /** @brief Get virual sensor config from DBus**/
    ManagedObjectType getObjectsFromDBus();
    /** @brief Parsing virtual sensor config JSON file  */
    Json parseConfigFile(const std::string& configFile);

    /** @brief Matches for virtual sensors */
    std::vector<std::unique_ptr<sdbusplus::bus::match_t>> matches;
    /** @brief Map of the object VirtualSensor */
    std::unordered_map<std::string, std::unique_ptr<VirtualSensor>>
        virtualSensorsMap;

    /** @brief Create list of virtual sensors from JSON config*/
    void createVirtualSensors();
    /** @brief Create list of virtual sensors from DBus config */
    void createVirtualSensorsFromDBus(const std::string& calculationType);
    /** @brief Setup matches for virtual sensors */
    void setupMatches();
};

} // namespace virtualSensor
} // namespace phosphor
