#pragma once

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

namespace phosphor
{
namespace dbus
{
namespace monitoring
{

/** @class JournalBase
 *  @brief Journal callback implementation.
 *
 *  The journal callback logs the client message and
 *  journal metadata key value pairs as specified by the
 *  client supplied property index.
 */
class JournalBase : public IndexedCallback
{
    public:
        JournalBase() = delete;
        JournalBase(const JournalBase&) = delete;
        JournalBase(JournalBase&&) = default;
        JournalBase& operator=(const JournalBase&) = delete;
        JournalBase& operator=(JournalBase&&) = default;
        virtual ~JournalBase() = default;
        JournalBase(const char* msg, const PropertyIndex& index) :
            IndexedCallback(index), message(msg) {}

        /** @brief Callback interface implementation. */
        void operator()() override;

    private:
        /** @brief Delegate type specific calls to subclasses. */
        virtual void log(
            const char* message,
            const std::string& pathMeta,
            const std::string& path,
            const std::string& propertyMeta,
            const any_ns::any& value) const = 0;

        /** @brief The client provided message to be traced.  */
        const char* message;
};

/** @struct Display
 *  @brief Convert strings to const char*.
 */
namespace detail
{
template <typename T> struct Display
{
    static auto op(T&& value)
    {
        return std::forward<T>(value);
    }
};

template <> struct Display<std::string>
{
    static auto op(const std::string& value)
    {
        return value.c_str();
    }
};
} // namespace detail

/** @class Journal
 *  @brief C++ type specific logic for the journal callback.
 *
 *  @tparam T - The C++ type of the property values being traced.
 *  @tparam Severity - The log severity of the log entry.
 */
template <typename T, phosphor::logging::level Severity>
class Journal : public JournalBase
{
    public:
        Journal() = delete;
        Journal(const Journal&) = delete;
        Journal(Journal&&) = default;
        Journal& operator=(const Journal&) = delete;
        Journal& operator=(Journal&&) = default;
        ~Journal() = default;
        Journal(const char* msg, const PropertyIndex& index) :
            JournalBase(msg, index) {}

    private:
        /** @brief log interface implementation. */
        void log(
            const char* message,
            const std::string& pathMeta,
            const std::string& path,
            const std::string& propertyMeta,
            const any_ns::any& value) const override
        {
            phosphor::logging::log<Severity>(
                message,
                phosphor::logging::entry(
                    (pathMeta + GetFormat<decltype(pathMeta)>::format).c_str(),
                    path.c_str()),
                phosphor::logging::entry(
                    (propertyMeta + GetFormat<T>::format).c_str(),
                    detail::Display<T>::op(any_ns::any_cast<T>(value))));
        }
};

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