#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
