#pragma once
#include <nlohmann/json.hpp>

#include <map>
#include <optional>
#include <string>
#include <vector>

namespace openpower
{
namespace pels
{

/**
 * @class AdditionalData
 *
 * This class takes in the contents of the AdditionalData OpenBMC
 * event log property, and provides access to its values based on
 * their keys.
 *
 * The property is a vector of strings of the form: "KEY=VALUE",
 * and this class provides a getValue("KEY") API that would return
 * "VALUE".
 */
class AdditionalData
{
  public:
    AdditionalData() = default;
    ~AdditionalData() = default;
    AdditionalData(const AdditionalData&) = default;
    AdditionalData& operator=(const AdditionalData&) = default;
    AdditionalData(AdditionalData&&) = default;
    AdditionalData& operator=(AdditionalData&&) = default;

    /**
     * @brief constructor
     *
     * @param[in] ad - the AdditionalData property vector with
     *                 entries of "KEY=VALUE"
     */
    explicit AdditionalData(const std::map<std::string, std::string>& ad) :
        _data(ad)
    {}

    /**
     * @brief Returns the value of the AdditionalData item for the
     *        key passed in.
     * @param[in] key - the key to search for
     *
     * @return optional<string> - the value, if found
     */
    std::optional<std::string> getValue(const std::string& key) const
    {
        auto entry = _data.find(key);
        if (entry != _data.end())
        {
            return entry->second;
        }
        return std::nullopt;
    }

    /**
     * @brief Remove a key/value pair from the contained data
     *
     * @param[in] key - The key of the entry to remove
     */
    void remove(const std::string& key)
    {
        _data.erase(key);
    }

    /**
     * @brief Says if the object has no data
     *
     * @return bool true if the object is empty
     */
    inline bool empty() const
    {
        return _data.empty();
    }

    /**
     * @brief Returns the contained data as a JSON object
     *
     * Looks like: {"key1":"value1","key2":"value2"}
     *
     * @return json - The JSON object
     */
    nlohmann::json toJSON() const
    {
        nlohmann::json j = _data;
        return j;
    }

    /**
     * @brief Returns the underlying map of data
     *
     * @return const std::map<std::string, std::string>& - The data
     */
    const std::map<std::string, std::string>& getData() const
    {
        return _data;
    }

    /**
     * @brief Adds a key/value pair to the object
     *
     * @param[in] key - The key
     * @param[in] value - The value
     */
    void add(const std::string& key, const std::string& value)
    {
        _data.emplace(key, value);
    }

  private:
    /**
     * @brief a map of keys to values
     */
    std::map<std::string, std::string> _data;
};
} // namespace pels
} // namespace openpower
