mgmt: Add router name configuration options

refs: #3026

Change-Id: I44250476e7e7f25cbc2b40d6a59f64b55872b24a
diff --git a/daemon/mgmt/general-config-section.cpp b/daemon/mgmt/general-config-section.cpp
index 02f45e8..4064548 100644
--- a/daemon/mgmt/general-config-section.cpp
+++ b/daemon/mgmt/general-config-section.cpp
@@ -35,6 +35,67 @@
 
 NFD_LOG_INIT("GeneralConfigSection");
 
+const ndn::Name
+RouterName::getName() const
+{
+  ndn::Name routerName;
+
+  if (network.empty() || site.empty() || router.empty())
+    {
+      return routerName;
+    }
+
+  routerName = network;
+  routerName.append(site);
+  routerName.append(ROUTER_MARKER);
+  routerName.append(router);
+
+  return routerName;
+}
+
+const ndn::PartialName RouterName::ROUTER_MARKER("%C1.Router");
+
+static RouterName&
+getRouterNameInstance()
+{
+  static RouterName routerName;
+  return routerName;
+}
+
+ndn::PartialName
+loadPartialNameFromSection(const ConfigSection& section, const std::string& key)
+{
+  ndn::PartialName value;
+
+  try
+    {
+      value = section.get<ndn::PartialName>(key);
+
+      if (value.empty())
+        {
+          throw ConfigFile::Error("Invalid value for \"router_name." + key + "\""
+                                  " in \"general\" section");
+        }
+    }
+  catch (const boost::property_tree::ptree_error& error)
+    {
+      throw ConfigFile::Error("Invalid value for \"router_name." + key + "\""
+                              " in \"general\" section");
+    }
+
+  return value;
+}
+
+void
+processSectionRouterName(const ConfigSection& section, bool isDryRun)
+{
+  RouterName& routerName = getRouterNameInstance();
+
+  routerName.network = loadPartialNameFromSection(section, "network");
+  routerName.site = loadPartialNameFromSection(section, "site");
+  routerName.router = loadPartialNameFromSection(section, "router");
+}
+
 static void
 onConfig(const ConfigSection& configSection,
          bool isDryRun,
@@ -44,6 +105,13 @@
   // {
   //    ; user "ndn-user"
   //    ; group "ndn-user"
+  //
+  //    ; router_name
+  //    ; {
+  //    ;   network ndn
+  //    ;   site    edu/site
+  //    ;   router  router/name
+  //    ; }
   // }
 
   std::string user;
@@ -93,6 +161,14 @@
   NFD_LOG_TRACE("using user \"" << user << "\" group \"" << group << "\"");
 
   PrivilegeHelper::initialize(user, group);
+
+  boost::optional<const ConfigSection&> routerNameSection =
+    configSection.get_child_optional("router_name");
+
+  if (routerNameSection)
+    {
+      processSectionRouterName(*routerNameSection, isDryRun);
+    }
 }
 
 void
@@ -101,6 +177,12 @@
   configFile.addSectionHandler("general", &onConfig);
 }
 
+const RouterName&
+getRouterName()
+{
+  return getRouterNameInstance();
+}
+
 } // namespace general
 
 } // namespace nfd
diff --git a/daemon/mgmt/general-config-section.hpp b/daemon/mgmt/general-config-section.hpp
index 6ce5473..e86abd2 100644
--- a/daemon/mgmt/general-config-section.hpp
+++ b/daemon/mgmt/general-config-section.hpp
@@ -25,6 +25,8 @@
 #ifndef NFD_MGMT_GENERAL_CONFIG_SECTION_HPP
 #define NFD_MGMT_GENERAL_CONFIG_SECTION_HPP
 
+#include <ndn-cxx/name.hpp>
+
 namespace nfd {
 
 class ConfigFile;
@@ -34,6 +36,33 @@
 void
 setConfigFile(ConfigFile& configFile);
 
+class RouterName
+{
+public:
+  /**
+   * \brief Return the router name constructed from the network, site, and
+   *        router variables.
+   *
+   *        The router name is constructed in the following manner:
+   *        /<network>/<site>/<ROUTER_MARKER>/<router>
+   *
+   * \return The constructed router name if the network, site, and router
+   *         configuration options are non-empty; otherwise, an empty ndn::Name.
+   */
+  const ndn::Name
+  getName() const;
+
+public:
+  ndn::PartialName network;
+  ndn::PartialName site;
+  ndn::PartialName router;
+
+  static const ndn::PartialName ROUTER_MARKER;
+};
+
+const RouterName&
+getRouterName();
+
 } // namespace general
 
 } // namespace nfd