#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
     *
     */
    VirtualSensor(sdbusplus::bus_t& bus, const char* objPath,
                  const InterfaceMap& ifacemap, const std::string& name,
                  const std::string& type, const std::string& calculationType) :
        ValueObject(bus, objPath, action::defer_emit),
        bus(bus), name(name)
    {
        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 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);
        }
    }
};

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
