Populate unique PrettyName as an extra interface

In vpd json, PrettyName has been moved from common interfaces
to extra interfaces, as a part of hardcoding unique names to
the frus.
Due to which the vpd-parser is populating xyz.openbmc_project.
Inventory.Item interface properties in two places.
Present property in common interface && PrettyName property in
extra interface.

std::emplace doesn't allows duplicate key emplacement. This commit
has a helper function which emplaces values into an already existing
key.

This commit also emplaces Present property to true whenever the parser
parses the eeprom, irrespective of "inherit" property in json.

Test:
Tested on simics.

root@p10bmc:/tmp# rm -rf /var/lib/phosphor-inventory-manager/xyz/openbmc_project/inventory/system/chassis/motherboard/ebmc_card_bmc/
root@p10bmc:/tmp#
root@p10bmc:/tmp# systemctl restart xyz.openbmc_project.Inventory.Manager.service
root@p10bmc:/tmp# ./ibm-read-vpd --file /sys/bus/i2c/drivers/at24/8-0051/eeprom

1. root@p10bmc:/tmp# busctl introspect xyz.openbmc_project.Inventory.Manager /xyz/openbmc_project/inventory/system/chassis/motherboard/ebmc_card_bmc/ethernet1
.....
....
xyz.openbmc_project.Inventory.Item                   interface -         -                            -
.Present                                             property  b         true                        emits-change writable
.PrettyName                                          property  s         "HMC Ethernet Connector"     emits-change writable

2. root@p10bmc:/tmp# busctl introspect xyz.openbmc_project.Inventory.Manager /xyz/openbmc_project/inventory/system/chassis/motherboard/ebmc_card_bmc/ethernet0
xyz.openbmc_project.Inventory.Item                    interface -         -                            -
.Present                                              property  b         true                         emits-change writable
.PrettyName                                           property  s         "HMC Ethernet Connector"     emits-change writable
xyz.openbmc_project.Inventory.Item.Connector          interface -         -                            -

3. root@p10bmc:/tmp# busctl introspect xyz.openbmc_project.Inventory.Manager /xyz/openbmc_project/inventory/system/chassis/motherboard/ebmc_card_bmc/displayport0
xyz.openbmc_project.Inventory.Item                   interface -         -                            -
.Present                                             property  b         true                         emits-change writable
.PrettyName                                          property  s         "Display Port Connector"     emits-change writable
xyz.openbmc_project.Inventory.Item.Connector         interface -         -

Signed-off-by: Priyanga Ramasamy <priyanga24@in.ibm.com>
Change-Id: I36c1e0bd3568c7fe26fa8592fb0268e091c41427
diff --git a/const.hpp b/const.hpp
index cf50452..eb4faa3 100644
--- a/const.hpp
+++ b/const.hpp
@@ -95,6 +95,7 @@
 constexpr auto systemVpdFilePath = "/sys/bus/i2c/drivers/at24/8-0050/eeprom";
 constexpr auto i2cPathPrefix = "/sys/bus/i2c/drivers/at24/";
 constexpr auto spiPathPrefix = "/sys/bus/spi/drivers/at25/";
+constexpr auto invItemIntf = "xyz.openbmc_project.Inventory.Item";
 
 namespace lengths
 {
diff --git a/ibm_vpd_app.cpp b/ibm_vpd_app.cpp
index 262c176..ae4d1be 100644
--- a/ibm_vpd_app.cpp
+++ b/ibm_vpd_app.cpp
@@ -321,7 +321,7 @@
                 props.emplace(busProp, itr.value().get<size_t>());
             }
         }
-        interfaces.emplace(inf, move(props));
+        insertOrMerge(interfaces, inf, move(props));
     }
 }
 
@@ -1294,6 +1294,10 @@
             populateInterfaces(item["extraInterfaces"], interfaces, vpdMap,
                                isSystemVpd);
         }
+        inventory::PropertyMap presProp;
+        presProp.emplace("Present", true);
+        insertOrMerge(interfaces, invItemIntf, move(presProp));
+
         objects.emplace(move(object), move(interfaces));
     }
 
diff --git a/ibm_vpd_utils.cpp b/ibm_vpd_utils.cpp
index 42bb99a..12c9a2d 100644
--- a/ibm_vpd_utils.cpp
+++ b/ibm_vpd_utils.cpp
@@ -613,5 +613,19 @@
     return str;
 }
 
+void insertOrMerge(inventory::InterfaceMap& map,
+                   const inventory::Interface& interface,
+                   inventory::PropertyMap&& property)
+{
+    if (map.find(interface) != map.end())
+    {
+        auto& prop = map.at(interface);
+        prop.insert(property.begin(), property.end());
+    }
+    else
+    {
+        map.emplace(interface, property);
+    }
+}
 } // namespace vpd
 } // namespace openpower
\ No newline at end of file
diff --git a/ibm_vpd_utils.hpp b/ibm_vpd_utils.hpp
index 6468067..11db6f7 100644
--- a/ibm_vpd_utils.hpp
+++ b/ibm_vpd_utils.hpp
@@ -260,5 +260,23 @@
  */
 string byteArrayToHexString(const Binary& vec);
 
+/**
+ * @brief Helper function to insert or merge in map.
+ *
+ * This method checks in the given inventory::InterfaceMap if the given
+ * interface key is existing or not. If the interface key already exists, given
+ * property map is inserted into it. If the key does'nt exist then given
+ * interface and property map pair is newly created. If the property present in
+ * propertymap already exist in the InterfaceMap, then the new property value is
+ * ignored.
+ *
+ * @param[in,out] map - map object of type inventory::InterfaceMap only.
+ * @param[in] interface - Interface name.
+ * @param[in] property - new property map that needs to be emplaced.
+ */
+void insertOrMerge(inventory::InterfaceMap& map,
+                   const inventory::Interface& interface,
+                   inventory::PropertyMap&& property);
+
 } // namespace vpd
 } // namespace openpower
\ No newline at end of file