#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
