## This file is a template.  The comment below is emitted
## into the rendered file; feel free to edit this file.
// WARNING: Generated header. Do not edit!


#pragma once

#include <map>
#include <iostream>
#include "defines.hpp"
#include "store.hpp"
#include "types.hpp"
#include "utils.hpp"
#include "extra-properties-gen.hpp"

namespace openpower
{
namespace vpd
{
namespace inventory
{

/** @brief API to write parsed VPD to inventory,
 *      for a specific FRU
 *
 *  @param [in] vpdStore - Store object containing
 *      parsed VPD
 *  @param [in] path - FRU object path
 */
template<Fru F>
void writeFru(const Store& /*vpdStore*/, const std::string& /*path*/) {
    throw std::runtime_error("Not implemented");
}

% for key in fruDict.keys():
<%
    fru = fruDict[key]
%>\
// Specialization of ${key}
template<>
void writeFru<Fru::${key}>(const Store& vpdStore,
                           const std::string& path)
{
    ObjectMap objects;
    InterfaceMap interfaces;
    auto iter = extra::objects.find(path);

    // Inventory manager needs object path, list of interface names to be
    // implemented, and property:value pairs contained in said interfaces

    % for interface, properties in fru.items():
<%
        names = interface.split(".")
        intfName = names[0] + names[-1]
%>\
    PropertyMap ${intfName}Props;
        % if properties:
            % for name, value in properties.items():
                % if fru and interface and name and value:
<%
                record, keyword = name.split(",")
%>\
    if (vpdStore.exists<Record::${record}, record::Keyword::${keyword}>())
    {
        ${intfName}Props["${value}"] =
            vpdStore.get<Record::${record}, record::Keyword::${keyword}>();
    }
                % endif
            % endfor
        % endif
    // Check and update extra properties
    if(extra::objects.end() != iter)
    {
        auto propIter = (iter->second).find("${interface}");
        if((iter->second).end() != propIter)
        {
            for(const auto& map : propIter->second)
            {
                ${intfName}Props[map.first] = map.second;
            }
        }
    }
    interfaces.emplace("${interface}",
                       std::move(${intfName}Props));
    % endfor

    sdbusplus::message::object_path object(path);
    // Check and update extra properties
    if(extra::objects.end() != iter)
    {
        for(const auto& entry : iter->second)
        {
            if(interfaces.end() == interfaces.find(entry.first))
            {
                interfaces.emplace(entry.first, entry.second);
            }
        }
    }
    objects.emplace(std::move(object), std::move(interfaces));

    callPIM(std::move(objects));
}

% endfor
} // namespace inventory
} // namespace vpd
} // namespace openpower
