poke: add --verbose option

Change-Id: I435f01cf6625bebbea40a0f808d8456fafb01fe1
diff --git a/manpages/ndnpoke.rst b/manpages/ndnpoke.rst
index f5ae345..7810a8c 100644
--- a/manpages/ndnpoke.rst
+++ b/manpages/ndnpoke.rst
@@ -4,7 +4,7 @@
 Synopsis
 --------
 
-**ndnpoke** [-h] [-f] [-F] [-x *freshness*] [-i *identity*\|\ -D] [-w *timeout*] [-V] *name*
+**ndnpoke** [-h] [-f] [-F] [-x *freshness*] [-i *identity*\|\ -D] [-w *timeout*] [-v] [-V] *name*
 
 Description
 -----------
@@ -38,6 +38,9 @@
 ``-w, --timeout <timeout>``
   Quit the program after ``timeout`` milliseconds, even if no Interest has been received.
 
+``-v, --verbose``
+  Turn on verbose output.
+
 ``-V, --version``
   Print version and exit.
 
diff --git a/tools/peek/ndnpoke/main.cpp b/tools/peek/ndnpoke/main.cpp
index fb26ab0..a327de0 100644
--- a/tools/peek/ndnpoke/main.cpp
+++ b/tools/peek/ndnpoke/main.cpp
@@ -61,6 +61,7 @@
     ("digest,D",    po::bool_switch(&wantDigestSha256),
                     "use DigestSha256 signing method instead of SignatureSha256WithRsa")
     ("timeout,w",   po::value<int>(), "set timeout (in milliseconds)")
+    ("verbose,v",   po::bool_switch(&options.isVerbose), "turn on verbose output")
     ("version,V",   "print version and exit")
   ;
 
diff --git a/tools/peek/ndnpoke/ndnpoke.cpp b/tools/peek/ndnpoke/ndnpoke.cpp
index 43acfb6..4db5ebf 100644
--- a/tools/peek/ndnpoke/ndnpoke.cpp
+++ b/tools/peek/ndnpoke/ndnpoke.cpp
@@ -47,30 +47,13 @@
   auto data = createData();
 
   if (m_options.wantForceData) {
-    m_face.put(*data);
-    m_result = Result::DATA_SENT;
-    return;
+    return sendData(*data);
   }
 
   m_registeredPrefix = m_face.setInterestFilter(m_options.name,
-    [this, data] (auto&&...) {
-      m_timeoutEvent.cancel();
-      m_face.put(*data);
-      m_result = Result::DATA_SENT;
-      m_registeredPrefix.cancel();
-    },
-    [this] (auto&&) {
-      if (m_options.timeout) {
-        m_timeoutEvent = m_scheduler.schedule(*m_options.timeout, [this] {
-          m_result = Result::TIMEOUT;
-          m_registeredPrefix.cancel();
-        });
-      }
-    },
-    [this] (auto&&, const auto& reason) {
-      m_result = Result::PREFIX_REG_FAIL;
-      std::cerr << "Prefix registration failure (" << reason << ")\n";
-    });
+    [this, data] (auto&&, const auto& interest) { this->onInterest(interest, *data); },
+    [this] (auto&&) { this->onRegSuccess(); },
+    [this] (auto&&, const auto& reason) { this->onRegFailure(reason); });
 }
 
 shared_ptr<Data>
@@ -93,5 +76,54 @@
   return data;
 }
 
+void
+NdnPoke::sendData(const Data& data)
+{
+  m_face.put(data);
+  m_result = Result::DATA_SENT;
+
+  if (m_options.isVerbose) {
+    std::cerr << "DATA: " << data;
+  }
+}
+
+void
+NdnPoke::onInterest(const Interest& interest, const Data& data)
+{
+  if (m_options.isVerbose) {
+    std::cerr << "INTEREST: " << interest << std::endl;
+  }
+
+  m_timeoutEvent.cancel();
+  m_registeredPrefix.cancel();
+  sendData(data);
+}
+
+void
+NdnPoke::onRegSuccess()
+{
+  if (m_options.isVerbose) {
+    std::cerr << "Prefix registration successful" << std::endl;
+  }
+
+  if (m_options.timeout) {
+    m_timeoutEvent = m_scheduler.schedule(*m_options.timeout, [this] {
+      m_result = Result::TIMEOUT;
+      m_registeredPrefix.cancel();
+
+      if (m_options.isVerbose) {
+        std::cerr << "TIMEOUT" << std::endl;
+      }
+    });
+  }
+}
+
+void
+NdnPoke::onRegFailure(const std::string& reason)
+{
+  m_result = Result::PREFIX_REG_FAIL;
+  std::cerr << "Prefix registration failure (" << reason << ")" << std::endl;
+}
+
 } // namespace peek
 } // namespace ndn
diff --git a/tools/peek/ndnpoke/ndnpoke.hpp b/tools/peek/ndnpoke/ndnpoke.hpp
index 6375512..adab5eb 100644
--- a/tools/peek/ndnpoke/ndnpoke.hpp
+++ b/tools/peek/ndnpoke/ndnpoke.hpp
@@ -47,6 +47,7 @@
   security::SigningInfo signingInfo;
 
   // program behavior options
+  bool isVerbose = false;
   bool wantForceData = false;
   optional<time::milliseconds> timeout;
 };
@@ -81,6 +82,18 @@
   shared_ptr<Data>
   createData() const;
 
+  void
+  sendData(const Data& data);
+
+  void
+  onInterest(const Interest& interest, const Data& data);
+
+  void
+  onRegSuccess();
+
+  void
+  onRegFailure(const std::string& reason);
+
 private:
   const PokeOptions m_options;
   Face& m_face;