#pragma once

#include <phosphor-logging/log.hpp>
#include "callback.hpp"
#include "event_manager.hpp"

#include <sstream>

namespace phosphor
{
namespace dbus
{
namespace monitoring
{

/** @class EventBase
 *  @brief Event callback implementation.
 *
 *  The event callback creates the event dbus object
 *  which has event message and metadata as key value pairs
 *  as specified by the client supplied property index.
 */
class EventBase : public IndexedCallback
{
    public:
        EventBase() = delete;
        EventBase(const EventBase&) = delete;
        EventBase(EventBase&&) = default;
        EventBase& operator=(const EventBase&) = delete;
        EventBase& operator=(EventBase&&) = default;
        virtual ~EventBase() = default;
        EventBase(const PropertyIndex& index) :
            IndexedCallback(index) {}

        /** @brief Callback interface implementation. */
        void operator()(Context ctx) override
        {
            if (ctx == Context::START)
            {
                // No action should be taken
                // as this call back is being called from
                // daemon Startup.
                return;
            }

            for (const auto& n : index)
            {
                const auto& path = std::get<pathIndex>(n.first);
                const auto& propertyMeta = std::get<propertyIndex>(n.first);
                const auto& storage = std::get<storageIndex>(n.second);
                const auto& value = std::get<valueIndex>(storage.get());

                if (!value.empty())
                {
                    createEvent(
                            path,
                            propertyMeta,
                            value);
                }
            }

        }

    private:

        /** @brief Create the event Dbus Object.
         *  @param[in] path - Dbus Object Path for which the
         *                    property has changed.
         *  @param[in] property - Name of the property whose value
         *                        has been changed.
         *  @param[in] value - Changed property value.
         */
        virtual void createEvent(
            const std::string& path,
            const std::string& property,
            const any_ns::any& value) const = 0;


};

/** @class Event
 *  @brief C++ type specific logic for the event callback.
 *
 *  @tparam T - The C++ type of the property values being traced.
 */
template <typename T>
class Event : public EventBase
{
    public:
        Event() = delete;
        Event(const Event&) = delete;
        Event(Event&&) = default;
        Event& operator=(const Event&) = delete;
        Event& operator=(Event&&) = default;
        ~Event() = default;

        /** @brief Constructor.
         *  @param[in] eventName - Name of the event.
         *  @param[in] eventMessage- Event Message.
         *  @param[in] index - look up index for the properties.
         */
        Event(std::string eventName,
              std::string eventMessage,
              const PropertyIndex& index) :
            EventBase(index),
            name(eventName),
            message(eventMessage) {}

    private:
        /** @brief Create the event Dbus Object.
         *  @param[in] path - Dbus Object Path for which the
         *                    property has changed.
         *  @param[in] property - Name of the property whose value
         *                        has been changed.
         *  @param[in] value - Changed property value.
         */
        void createEvent(
            const std::string& path,
            const std::string& property,
            const any_ns::any& value) const override
        {
            std::stringstream ss {};
            ss << any_ns::any_cast<T>(value);
            phosphor::events::getManager().create(
                name, message, path, property, ss.str());
        }

        /** @brief Event Name */
        std::string name;

        /** @brief Event Message */
        std::string message;
};

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