Restore routable prefix discovery in Dispatcher module

Change-Id: I8ba52ca784d8ab3c1afb56fc468986904cca8d35
diff --git a/gui/chronosharegui.cpp b/gui/chronosharegui.cpp
index cce3a2a..687d14c 100644
--- a/gui/chronosharegui.cpp
+++ b/gui/chronosharegui.cpp
@@ -166,9 +166,9 @@
   fs::path realPathToFolder(m_dirPath.toStdString());
   realPathToFolder /= m_sharedFolderName.toStdString();
 
-  std::cout << "m_dispatcher username:" << m_username.toStdString()
+  _LOG_DEBUG("m_dispatcher username:" << m_username.toStdString()
             << " m_sharedFolderName:" << m_sharedFolderName.toStdString()
-            << " realPathToFolder: " << realPathToFolder << std::endl;
+            << " realPathToFolder: " << realPathToFolder);
 
   m_ioService.reset(new boost::asio::io_service());
   m_face.reset(new Face(*m_ioService));
diff --git a/src/dispatcher.cpp b/src/dispatcher.cpp
index bf0856e..cae79a2 100644
--- a/src/dispatcher.cpp
+++ b/src/dispatcher.cpp
@@ -38,16 +38,18 @@
 static const Name BROADCAST_DOMAIN = "/ndn/multicast";
 
 static const time::seconds DEFAULT_SYNC_INTEREST_INTERVAL = time::seconds(10);
+static const time::seconds DEFAULT_AUTO_DISCOVERY_INTERVAL = time::seconds(60);
 
 Dispatcher::Dispatcher(const std::string& localUserName, const std::string& sharedFolder,
-                       const fs::path& rootDir, Face& face, bool enablePrefixDiscovery)
+                       const fs::path& rootDir, Face& face)
   : m_face(face)
   , m_rootDir(rootDir)
   , m_ioService(face.getIoService())
+  , m_scheduler(m_ioService)
+  , m_autoDiscovery(m_scheduler)
   , m_objectManager(face, m_keyChain, rootDir, CHRONOSHARE_APP.toUri())
   , m_localUserName(localUserName)
   , m_sharedFolder(sharedFolder)
-  , m_enablePrefixDiscovery(enablePrefixDiscovery)
 {
   m_syncLog = make_shared<SyncLog>(m_rootDir, localUserName);
   m_actionLog =
@@ -90,32 +92,55 @@
                               bind(&Dispatcher::Did_FetchManager_FileFetchComplete, this, _1, _2),
                               fileTaskDb);
 
-  if (m_enablePrefixDiscovery) {
-    _LOG_DEBUG("registering prefix discovery in Dispatcher");
-    std::string tag = "dispatcher" + m_localUserName.toUri();
-    // Ccnx::CcnxDiscovery::registerCallback(TaggedFunction(bind(&Dispatcher::Did_LocalPrefix_Updated,
-    // this, _1), tag));
-    // TODO registerCallback...?
-    //
-    // this registerCallback is used when the local prefix changes.
-    // the ndn-cxx library does not have this functionality
-    // thus, the application will need to implement this.
-    // send a data packet and get the local prefix. If they are different, call the callback
-    // function, else do nothing.
-  }
+  _LOG_DEBUG("registering prefix discovery in Dispatcher");
+  m_autoDiscovery = m_scheduler.scheduleEvent(DEFAULT_AUTO_DISCOVERY_INTERVAL,
+                                              bind(&Dispatcher::DiscoverPrefix, this));
 }
 
 Dispatcher::~Dispatcher()
 {
   _LOG_DEBUG("Enter destructor of dispatcher");
+}
 
-  if (m_enablePrefixDiscovery) {
-    _LOG_DEBUG("deregistering prefix discovery in Dispatcher");
-    std::string tag = "dispatcher" + m_localUserName.toUri();
-    // TODO
-    //    Ccnx::CcnxDiscovery::deregisterCallback(TaggedFunction(bind(&Dispatcher::Did_LocalPrefix_Updated,
-    //    this, _1), tag));
+void
+Dispatcher::DiscoverPrefix()
+{
+  _LOG_DEBUG("Query for local prefix");
+  Interest interest(Name("/localhop/nfd/rib/routable-prefixes"));
+  m_face.expressInterest(interest,
+      bind(&Dispatcher::Handle_Prefix_Discovery, this, _1, _2),
+      bind([this] {m_autoDiscovery = m_scheduler.scheduleEvent(DEFAULT_AUTO_DISCOVERY_INTERVAL,
+                                                               bind(&Dispatcher::DiscoverPrefix, this));
+                   _LOG_DEBUG("query routable-prefixes, nack received"); }),
+      bind([this] {m_autoDiscovery = m_scheduler.scheduleEvent(DEFAULT_AUTO_DISCOVERY_INTERVAL,
+                                                               bind(&Dispatcher::DiscoverPrefix, this));
+                   _LOG_DEBUG("query routable-prefixes interest timeout"); }));
+}
+
+void
+Dispatcher::Handle_Prefix_Discovery(const Interest& interest, const Data& data)
+{
+  const Block& content = data.getContent();
+  content.parse();
+
+  Name prefix;
+
+  for (auto& element : content.elements()) {
+    prefix = Name(element);
+    break;
   }
+
+  _LOG_DEBUG("local prefix:" << prefix << prefix.empty());
+  if(prefix.empty()) {
+    _LOG_DEBUG("Local prefix is empty");
+    return;
+  }
+
+  _LOG_DEBUG("local prefix:" << prefix << "discovered");
+  Did_LocalPrefix_Updated(prefix);
+
+  m_autoDiscovery = m_scheduler.scheduleEvent(DEFAULT_AUTO_DISCOVERY_INTERVAL,
+                                              bind(&Dispatcher::DiscoverPrefix, this));
 }
 
 void
@@ -222,7 +247,7 @@
     // notify SyncCore to propagate the change
     m_core->localStateChangedDelayed();
   }
-  catch (fs::filesystem_error& error) {
+  catch (const fs::filesystem_error& error) {
     _LOG_ERROR("File operations failed on [" << relativeFilePath << "](ignoring)");
   }
 
@@ -350,7 +375,7 @@
     }
     // don't exist
   }
-  catch (fs::filesystem_error& error) {
+  catch (const fs::filesystem_error& error) {
     _LOG_ERROR("File operations failed when removing [" << absolutePath << "](ignoring)");
   }
 }
@@ -436,7 +461,7 @@
           }
       }
     }
-    catch (fs::filesystem_error& error) {
+    catch (const fs::filesystem_error& error) {
       _LOG_ERROR("File operations failed on [" << filePath << "](ignoring)");
     }
 
diff --git a/src/dispatcher.hpp b/src/dispatcher.hpp
index 45d6718..e05116e 100644
--- a/src/dispatcher.hpp
+++ b/src/dispatcher.hpp
@@ -68,7 +68,7 @@
   // sharedFolder is the name to be used in NDN name;
   // rootDir is the shared folder dir in local file system;
   Dispatcher(const std::string& localUserName, const std::string& sharedFolder,
-             const boost::filesystem::path& rootDir, Face& face, bool enablePrefixDiscovery = true);
+             const boost::filesystem::path& rootDir, Face& face);
   ~Dispatcher();
 
   // ----- Callbacks, they only submit the job to executor and immediately return so that event
@@ -154,12 +154,6 @@
   void
   Did_ActionLog_ActionApply_Delete_Execute(std::string filename);
 
-  // void
-  // Did_ActionLog_ActionApply_AddOrModify(const std::string &filename, Name device_name,
-  // sqlite3_int64 seq_no,
-  //                                        ConstBufferPtr hash, time_t m_time, int mode, int
-  //                                        seg_num);
-
   void
   Did_FetchManager_FileSegmentFetch(const Name& deviceName, const Name& fileSegmentName,
                                     uint32_t segment, shared_ptr<Data> fileSegmentData);
@@ -175,6 +169,12 @@
   Did_FetchManager_FileFetchComplete_Execute(Name deviceName, Name fileBaseName);
 
   void
+  Handle_Prefix_Discovery(const Interest& interest, const Data& data);
+
+  void
+  DiscoverPrefix();
+
+  void
   Did_LocalPrefix_Updated(const Name& prefix);
 
 private:
@@ -182,21 +182,6 @@
   AssembleFile_Execute(const Name& deviceName, const Buffer& filehash,
                        const boost::filesystem::path& relativeFilepath);
 
-  // void
-  // fileChanged(const boost::filesystem::path &relativeFilepath, ActionType type);
-
-  // void
-  // syncStateChanged(const SyncStateMsgPtr &stateMsg);
-
-  // void
-  // actionReceived(const ActionItemPtr &actionItem);
-
-  // void
-  // fileSegmentReceived(const Name &name, const Ccnx::Bytes &content);
-
-  // void
-  // fileReady(const Name &fileNamePrefix);
-
 private:
   Face& m_face;
   unique_ptr<SyncCore> m_core;
@@ -207,6 +192,8 @@
 
   boost::filesystem::path m_rootDir;
   boost::asio::io_service& m_ioService;
+  Scheduler m_scheduler;
+  util::scheduler::ScopedEventId m_autoDiscovery;
 
   ObjectManager m_objectManager;
   Name m_localUserName;
@@ -218,7 +205,6 @@
   std::string m_sharedFolder;
   unique_ptr<ContentServer> m_server;
   unique_ptr<StateServer> m_stateServer;
-  bool m_enablePrefixDiscovery;
 
   FetchManagerPtr m_actionFetcher;
   FetchManagerPtr m_fileFetcher;
diff --git a/tests/unit-tests/dispatcher.t.cpp b/tests/unit-tests/dispatcher.t.cpp
index 60f0505..bb74d7b 100644
--- a/tests/unit-tests/dispatcher.t.cpp
+++ b/tests/unit-tests/dispatcher.t.cpp
@@ -77,8 +77,8 @@
 
 BOOST_AUTO_TEST_CASE(DispatcherTest)
 {
-  Dispatcher d1(user1, folder, dir1, face1, false);
-  Dispatcher d2(user2, folder, dir2, face2, false);
+  Dispatcher d1(user1, folder, dir1, face1);
+  Dispatcher d2(user2, folder, dir2, face2);
 
   advanceClocks(time::milliseconds(10), 1000);