#pragma once

#include "dbus_types.hpp"

#include <sdbusplus/bus/match.hpp>

namespace openpower::pels
{

namespace match_rules = sdbusplus::bus::match::rules;

/**
 * @class DBusWatcher
 *
 * The base class for the PropertyWatcher and InterfaceWatcher classes.
 */
class DBusWatcher
{
  public:
    DBusWatcher() = delete;
    virtual ~DBusWatcher() = default;
    DBusWatcher(const DBusWatcher&) = default;
    DBusWatcher& operator=(const DBusWatcher&) = default;
    DBusWatcher(DBusWatcher&&) = default;
    DBusWatcher& operator=(DBusWatcher&&) = default;

    /**
     * @brief Constructor
     *
     * @param[in] path - The D-Bus path that will be watched
     * @param[in] interface - The D-Bus interface that will be watched
     */
    DBusWatcher(const std::string& path, const std::string& interface) :
        _path(path), _interface(interface)
    {
    }

  protected:
    /**
     * @brief The D-Bus path
     */
    std::string _path;

    /**
     * @brief The D-Bus interface
     */
    std::string _interface;

    /**
     * @brief The match objects for the propertiesChanged and
     *        interfacesAdded signals.
     */
    std::vector<sdbusplus::bus::match_t> _matches;
};

/**
 * @class PropertyWatcher
 *
 * This class allows the user to be kept up to data with a D-Bus
 * property's value.  It does this by calling a user specified function
 * that is passed the variant that contains the property's value when:
 *
 * 1) The property is read when the class is constructed, if
 *    the property is on D-Bus at the time.
 * 2) The property changes (via a property changed signal).
 * 3) An interfacesAdded signal is received with that property.
 *
 * The DataInterface class is used to access D-Bus, and is a template
 * to avoid any circular include issues as that class is one of the
 * users of this one.
 */
template <typename DataIface>
class PropertyWatcher : public DBusWatcher
{
  public:
    PropertyWatcher() = delete;
    ~PropertyWatcher() = default;
    PropertyWatcher(const PropertyWatcher&) = delete;
    PropertyWatcher& operator=(const PropertyWatcher&) = delete;
    PropertyWatcher(PropertyWatcher&&) = delete;
    PropertyWatcher& operator=(PropertyWatcher&&) = delete;

    using PropertySetFunc = std::function<void(const DBusValue&)>;

    /**
     * @brief Constructor
     *
     * Reads the property if it is on D-Bus, and sets up the match
     * objects for the propertiesChanged and interfacesAdded signals.
     *
     * @param[in] bus - The sdbusplus bus object
     * @param[in] path - The D-Bus path of the property
     * @param[in] interface - The D-Bus interface that contains the property
     * @param[in] propertyName - The property name
     * @param[in] service - The D-Bus service to use for the property read.
     *                      Can be empty to look it up instead.
     * @param[in] dataIface - The DataInterface object
     * @param[in] func - The callback used any time the property is read
     */
    PropertyWatcher(sdbusplus::bus_t& bus, const std::string& path,
                    const std::string& interface,
                    const std::string& propertyName, const std::string& service,
                    const DataIface& dataIface, PropertySetFunc func) :
        DBusWatcher(path, interface),
        _name(propertyName), _setFunc(func)
    {
        _matches.emplace_back(
            bus, match_rules::propertiesChanged(_path, _interface),
            std::bind(std::mem_fn(&PropertyWatcher::propChanged), this,
                      std::placeholders::_1));

        _matches.emplace_back(
            bus,
            match_rules::interfacesAdded() + match_rules::argNpath(0, _path),
            std::bind(std::mem_fn(&PropertyWatcher::interfaceAdded), this,
                      std::placeholders::_1));

        try
        {
            read(dataIface, service);
        }
        catch (const sdbusplus::exception_t& e)
        {
            // Path doesn't exist now
        }
    }

    /**
     * @brief Constructor
     *
     * Reads the property if it is on D-Bus, and sets up the match
     * objects for the propertiesChanged and interfacesAdded signals.
     *
     * Unlike the other constructor, this contructor doesn't take the
     * service to use for the property read so it will look it up with
     * an ObjectMapper GetObject call.
     *
     * @param[in] bus - The sdbusplus bus object
     * @param[in] path - The D-Bus path of the property
     * @param[in] interface - The D-Bus interface that contains the property
     * @param[in] propertyName - The property name
     * @param[in] dataIface - The DataInterface object
     * @param[in] func - The callback used any time the property is read
     */
    PropertyWatcher(sdbusplus::bus_t& bus, const std::string& path,
                    const std::string& interface,
                    const std::string& propertyName, const DataIface& dataIface,
                    PropertySetFunc func) :
        PropertyWatcher(bus, path, interface, propertyName, "", dataIface, func)
    {
    }

    /**
     * @brief Reads the property on D-Bus, and calls
     *        the user defined function with the value.
     *
     * If the passed in service is empty, look up the service to use.
     *
     * @param[in] dataIface - The DataInterface object
     * @param[in] service - The D-Bus service to make the getProperty
     *                      call with, if not empty
     */
    void read(const DataIface& dataIface, std::string service)
    {
        if (service.empty())
        {
            service = dataIface.getService(_path, _interface);
        }

        if (!service.empty())
        {
            DBusValue value;
            dataIface.getProperty(service, _path, _interface, _name, value);

            _setFunc(value);
        }
    }

    /**
     * @brief The propertiesChanged callback
     *
     * Calls the user defined function with the property value
     *
     * @param[in] msg - The sdbusplus message object
     */
    void propChanged(sdbusplus::message_t& msg)
    {
        DBusInterface interface;
        DBusPropertyMap properties;

        msg.read(interface, properties);

        auto prop = properties.find(_name);
        if (prop != properties.end())
        {
            _setFunc(prop->second);
        }
    }

    /**
     * @brief The interfacesAdded callback
     *
     * Calls the user defined function with the property value
     *
     * @param[in] msg - The sdbusplus message object
     */
    void interfaceAdded(sdbusplus::message_t& msg)
    {
        sdbusplus::message::object_path path;
        DBusInterfaceMap interfaces;

        msg.read(path, interfaces);

        auto iface = interfaces.find(_interface);
        if (iface != interfaces.end())
        {
            auto prop = iface->second.find(_name);
            if (prop != iface->second.end())
            {
                _setFunc(prop->second);
            }
        }
    }

  private:
    /**
     * @brief The D-Bus property name
     */
    std::string _name;

    /**
     * @brief The function that will be called any time the
     *        property is read.
     */
    PropertySetFunc _setFunc;
};

/**
 * @class InterfaceWatcher
 *
 * This class allows the user to be kept up to data with a D-Bus
 * interface's properties..  It does this by calling a user specified
 * function that is passed a map of the D-Bus property names and values
 * on that interface when:
 *
 * 1) The interface is read when the class is constructed, if
 *    the interface is on D-Bus at the time.
 * 2) The interface has a property that changes (via a property changed signal).
 * 3) An interfacesAdded signal is received.
 *
 * The DataInterface class is used to access D-Bus, and is a template
 * to avoid any circular include issues as that class is one of the
 * users of this one.
 */
template <typename DataIface>
class InterfaceWatcher : public DBusWatcher
{
  public:
    InterfaceWatcher() = delete;
    ~InterfaceWatcher() = default;
    InterfaceWatcher(const InterfaceWatcher&) = delete;
    InterfaceWatcher& operator=(const InterfaceWatcher&) = delete;
    InterfaceWatcher(InterfaceWatcher&&) = delete;
    InterfaceWatcher& operator=(InterfaceWatcher&&) = delete;

    using InterfaceSetFunc = std::function<void(const DBusPropertyMap&)>;

    /**
     * @brief Constructor
     *
     * Reads all properties on the interface if it is on D-Bus,
     * and sets up the match objects for the propertiesChanged
     * and interfacesAdded signals.
     *
     * @param[in] bus - The sdbusplus bus object
     * @param[in] path - The D-Bus path of the property
     * @param[in] interface - The D-Bus interface that contains the property
     * @param[in] dataIface - The DataInterface object
     * @param[in] func - The callback used any time the property is read
     */
    InterfaceWatcher(sdbusplus::bus_t& bus, const std::string& path,
                     const std::string& interface, const DataIface& dataIface,
                     InterfaceSetFunc func) :
        DBusWatcher(path, interface),
        _setFunc(func)
    {
        _matches.emplace_back(
            bus, match_rules::propertiesChanged(_path, _interface),
            std::bind(std::mem_fn(&InterfaceWatcher::propChanged), this,
                      std::placeholders::_1));

        _matches.emplace_back(
            bus,
            match_rules::interfacesAdded() + match_rules::argNpath(0, _path),
            std::bind(std::mem_fn(&InterfaceWatcher::interfaceAdded), this,
                      std::placeholders::_1));

        try
        {
            read(dataIface);
        }
        catch (const sdbusplus::exception_t& e)
        {
            // Path doesn't exist now
        }
    }

    /**
     * @brief Reads the interface's properties on D-Bus, and
     * calls the the user defined function with the property map.
     *
     * @param[in] dataIface - The DataInterface object
     */
    void read(const DataIface& dataIface)
    {
        auto service = dataIface.getService(_path, _interface);
        if (!service.empty())
        {
            auto properties =
                dataIface.getAllProperties(service, _path, _interface);

            _setFunc(properties);
        }
    }

    /**
     * @brief The propertiesChanged callback
     *
     * Calls the user defined function with the property map.  Only the
     * properties that changed will be in the map.
     *
     * @param[in] msg - The sdbusplus message object
     */
    void propChanged(sdbusplus::message_t& msg)
    {
        DBusInterface interface;
        DBusPropertyMap properties;

        msg.read(interface, properties);

        _setFunc(properties);
    }

    /**
     * @brief The interfacesAdded callback
     *
     * Calls the user defined function with the property map
     *
     * @param[in] msg - The sdbusplus message object
     */
    void interfaceAdded(sdbusplus::message_t& msg)
    {
        sdbusplus::message::object_path path;
        DBusInterfaceMap interfaces;

        msg.read(path, interfaces);

        auto iface = interfaces.find(_interface);
        if (iface != interfaces.end())
        {
            _setFunc(iface->second);
        }
    }

  private:
    /**
     * @brief The function that will be called any time the
     *        interface is read.
     */
    InterfaceSetFunc _setFunc;
};

} // namespace openpower::pels
