/**
 * @file propertywatch.hpp
 * @brief PropertyWatch class declarations.
 *
 * In general class users should include propertywatchimpl.hpp instead to avoid
 * link failures.
 */
#pragma once

#include "data_types.hpp"
#include "watch.hpp"

namespace phosphor
{
namespace dbus
{
namespace monitoring
{

class Callback;

/** @class PropertyWatch
 *  @brief Type agnostic, factored out logic for property watches.
 *
 *  A property watch maintains the state of one or more DBus properties
 *  as specified by the supplied index.
 */
template <typename DBusInterfaceType>
class PropertyWatch : public Watch
{
    public:
        PropertyWatch() = delete;
        PropertyWatch(const PropertyWatch&) = delete;
        PropertyWatch(PropertyWatch&&) = default;
        PropertyWatch& operator=(const PropertyWatch&) = delete;
        PropertyWatch& operator=(PropertyWatch&&) = default;
        virtual ~PropertyWatch() = default;
        PropertyWatch(
            const PropertyIndex& watchIndex,
            Callback* callback = nullptr)
            : Watch(), index(watchIndex), cb(callback), alreadyRan(false) {}

        /** @brief Start the watch.
         *
         *  Watch start interface implementation for PropertyWatch.
         */
        void start() override;

        /** @brief Run the watch callback method.
         *
         *  Watch callback interface implementation for PropertyWatch.
         */
        void callback() override;

        /** @brief Update properties.
         *
         *  Subclasses to query the properties specified by the index
         *  and update the cache.
         *
         *  @param[in] busName - The busname hosting the interface to query.
         *  @param[in] path - The path of the interface to query.
         *  @param[in] interface - The interface to query.
         */
        virtual void updateProperties(
            const std::string& busName,
            const std::string& path,
            const std::string& interface) = 0;

        /** @brief Dbus signal callback for PropertiesChanged.
         *
         *  Subclasses to update the cache.
         *
         *  @param[in] message - The org.freedesktop.DBus.PropertiesChanged
         *               message.
         *  @param[in] path - The path associated with the message.
         *  @param[in] interface - The interface associated with the message.
         */
        virtual void propertiesChanged(
            sdbusplus::message::message&,
            const std::string& path,
            const std::string& interface) = 0;

        /** @brief Dbus signal callback for InterfacesAdded.
         *
         *  Subclasses to update the cache.
         *
         *  @param[in] msg - The org.freedesktop.DBus.PropertiesChanged
         *               message.
         */
        virtual void interfacesAdded(sdbusplus::message::message& msg) = 0;

    protected:

        /** @brief Property names and their associated storage. */
        const PropertyIndex& index;

        /** @brief Optional callback method. */
        Callback* const cb;

        /** @brief The start method should only be invoked once. */
        bool alreadyRan;
};

/** @class PropertyWatchOfType
 *  @brief Type specific logic for PropertyWatch.
 *
 *  @tparam DBusInterfaceType - DBus access delegate.
 *  @tparam T - The type of the properties being watched.
 */
template <typename T, typename DBusInterfaceType>
class PropertyWatchOfType : public PropertyWatch<DBusInterfaceType>
{
    public:
        PropertyWatchOfType() = default;
        PropertyWatchOfType(const PropertyWatchOfType&) = delete;
        PropertyWatchOfType(PropertyWatchOfType&&) = default;
        PropertyWatchOfType& operator=(const PropertyWatchOfType&) = delete;
        PropertyWatchOfType& operator=(PropertyWatchOfType&&) = default;
        ~PropertyWatchOfType() = default;
        PropertyWatchOfType(
            const PropertyIndex& watchIndex, Callback& callback) :
            PropertyWatch<DBusInterfaceType>(watchIndex, &callback) {}
        PropertyWatchOfType(
            const PropertyIndex& watchIndex) :
            PropertyWatch<DBusInterfaceType>(watchIndex, nullptr) {}


        /** @brief PropertyMatch implementation for PropertyWatchOfType.
         *
         *  @param[in] busName - The busname hosting the interface to query.
         *  @param[in] path - The path of the interface to query.
         *  @param[in] interface - The interface to query.
         */
        void updateProperties(
            const std::string& busName,
            const std::string& path,
            const std::string& interface) override;

        /** @brief PropertyMatch implementation for PropertyWatchOfType.
         *
         *  @param[in] msg - The org.freedesktop.DBus.PropertiesChanged
         *               message.
         *  @param[in] path - The path associated with the message.
         *  @param[in] interface - The interface associated with the message.
         */
        void propertiesChanged(
            sdbusplus::message::message& msg,
            const std::string& path,
            const std::string& interface) override;

        /** @brief DBus agnostic implementation of interfacesAdded.
         *
         *  @param[in] path - The path of the properties that changed.
         *  @param[in] interface - The interface of the properties that
         *                  changed.
         *  @param[in] properites - The properties that changed.
         */
        void propertiesChanged(
            const std::string& path,
            const std::string& interface,
            const PropertiesChanged<T>& properties);

        /** @brief PropertyMatch implementation for PropertyWatchOfType.
         *
         *  @param[in] msg - The org.freedesktop.DBus.PropertiesChanged
         *               message.
         */
        void interfacesAdded(sdbusplus::message::message& msg) override;

        /** @brief DBus agnostic implementation of interfacesAdded.
         *
         *  @param[in] path - The path of the added interfaces.
         *  @param[in] interfaces - The added interfaces.
         */
        void interfacesAdded(
            const std::string& path,
            const InterfacesAdded<T>& interfaces);
};

} // namespace monitoring
} // namespace dbus
} // namespace phosphor
