poke: rename -f/--force option to -u/--unsolicited

The old name will still be accepted for some time,
but will print a deprecation warning if used.

This commit also improves --help output.

Change-Id: I2ebac82423a5276109f4b40b382312bd852419de
diff --git a/manpages/ndnpoke.rst b/manpages/ndnpoke.rst
index 7810a8c..5f704ee 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] [-V] *name*
+**ndnpoke** [-h] [-u] [-F] [-x *freshness*] [-i *identity*\|\ -D] [-w *timeout*] [-v] [-V] *name*
 
 Description
 -----------
@@ -12,7 +12,7 @@
 :program:`ndnpoke` is a simple producer program that reads a payload from the standard
 input and publishes it as a single Data packet. The Data packet is either sent as a
 response to an incoming Interest matching *name*, or immediately pushed to the local
-NDN forwarder as "unsolicited Data" if the **-f** flag is specified.
+NDN forwarder as "unsolicited Data" if the **-u** flag is specified.
 
 Options
 -------
@@ -20,7 +20,7 @@
 ``-h, --help``
   Print help and exit.
 
-``-f, --force``
+``-u, --unsolicited``
   Send the Data packet without waiting for an incoming Interest.
 
 ``-F, --final``
diff --git a/tests/peek/ndnpoke.t.cpp b/tests/peek/ndnpoke.t.cpp
index 9bf51cf..621a699 100644
--- a/tests/peek/ndnpoke.t.cpp
+++ b/tests/peek/ndnpoke.t.cpp
@@ -180,10 +180,10 @@
   BOOST_CHECK_EQUAL(face.sentData.back().getSignature().getType(), tlv::DigestSha256);
 }
 
-BOOST_AUTO_TEST_CASE(ForceData)
+BOOST_AUTO_TEST_CASE(Unsolicited)
 {
   auto options = makeDefaultOptions();
-  options.wantForceData = true;
+  options.wantUnsolicited = true;
   initialize(options);
 
   poke->start();
diff --git a/tools/peek/ndnpoke/main.cpp b/tools/peek/ndnpoke/main.cpp
index a327de0..913b0a8 100644
--- a/tools/peek/ndnpoke/main.cpp
+++ b/tools/peek/ndnpoke/main.cpp
@@ -23,6 +23,7 @@
  * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
  *
  * @author Jerald Paul Abraham <jeraldabraham@email.arizona.edu>
+ * @author Davide Pesavento <davidepesa@gmail.com>
  */
 
 #include "ndnpoke.hpp"
@@ -49,28 +50,41 @@
   PokeOptions options;
   bool wantDigestSha256 = false;
 
-  po::options_description visibleOptDesc;
-  visibleOptDesc.add_options()
-    ("help,h",      "print help and exit")
-    ("force,f",     po::bool_switch(&options.wantForceData),
-                    "send the Data packet without waiting for an incoming Interest")
+  po::options_description genericOptDesc("Generic options");
+  genericOptDesc.add_options()
+    ("help,h",        "print help and exit")
+    ("unsolicited,u", po::bool_switch(&options.wantUnsolicited),
+                      "send the Data packet without waiting for an incoming Interest")
+    ("timeout,w",     po::value<time::milliseconds::rep>(), "set timeout (in milliseconds)")
+    ("verbose,v",     po::bool_switch(&options.isVerbose), "turn on verbose output")
+    ("version,V",     "print version and exit")
+  ;
+
+  po::options_description dataOptDesc("Data construction");
+  dataOptDesc.add_options()
     ("final,F",     po::bool_switch(&options.wantFinalBlockId),
                     "set FinalBlockId to the last component of the Data name")
-    ("freshness,x", po::value<int>(), "set FreshnessPeriod (in milliseconds)")
+    ("freshness,x", po::value<time::milliseconds::rep>()->default_value(options.freshnessPeriod.count()),
+                    "set FreshnessPeriod (in milliseconds)")
     ("identity,i",  po::value<std::string>(), "use the specified identity for signing")
     ("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")
   ;
 
+  po::options_description visibleOptDesc;
+  visibleOptDesc.add(genericOptDesc).add(dataOptDesc);
+
   po::options_description hiddenOptDesc;
   hiddenOptDesc.add_options()
     ("name", po::value<std::string>(), "Data name");
 
+  po::options_description deprecatedOptDesc;
+  deprecatedOptDesc.add_options()
+    ("force,f", po::bool_switch())
+  ;
+
   po::options_description optDesc;
-  optDesc.add(visibleOptDesc).add(hiddenOptDesc);
+  optDesc.add(visibleOptDesc).add(hiddenOptDesc).add(deprecatedOptDesc);
 
   po::positional_options_description optPos;
   optPos.add("name", -1);
@@ -85,6 +99,12 @@
     return 2;
   }
 
+  if (vm["force"].as<bool>()) {
+    std::cerr << "WARNING: option '-f/--force' is deprecated and will be removed "
+                 "in the near future. Use '-u/--unsolicited' instead." << std::endl;
+    options.wantUnsolicited = true;
+  }
+
   if (vm.count("help") > 0) {
     usage(std::cout, progName, visibleOptDesc);
     return 0;
@@ -115,11 +135,12 @@
   }
 
   if (vm.count("freshness") > 0) {
-    if (vm["freshness"].as<int>() < 0) {
+    auto freshness = vm["freshness"].as<time::milliseconds::rep>();
+    if (freshness < 0) {
       std::cerr << "ERROR: freshness cannot be negative" << std::endl;
       return 2;
     }
-    options.freshnessPeriod = time::milliseconds(vm["freshness"].as<int>());
+    options.freshnessPeriod = time::milliseconds(freshness);
   }
 
   if (vm.count("identity") > 0) {
@@ -141,15 +162,16 @@
   }
 
   if (vm.count("timeout") > 0) {
-    if (options.wantForceData) {
-      std::cerr << "ERROR: conflicting '--force' and '--timeout' options specified" << std::endl;
+    if (options.wantUnsolicited) {
+      std::cerr << "ERROR: conflicting '--unsolicited' and '--timeout' options specified" << std::endl;
       return 2;
     }
-    if (vm["timeout"].as<int>() < 0) {
+    auto timeout = vm["timeout"].as<time::milliseconds::rep>();
+    if (timeout < 0) {
       std::cerr << "ERROR: timeout cannot be negative" << std::endl;
       return 2;
     }
-    options.timeout = time::milliseconds(vm["timeout"].as<int>());
+    options.timeout = time::milliseconds(timeout);
   }
 
   try {
diff --git a/tools/peek/ndnpoke/ndnpoke.cpp b/tools/peek/ndnpoke/ndnpoke.cpp
index 4cbe0e8..d31a939 100644
--- a/tools/peek/ndnpoke/ndnpoke.cpp
+++ b/tools/peek/ndnpoke/ndnpoke.cpp
@@ -23,6 +23,7 @@
  * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
  *
  * @author Jerald Paul Abraham <jeraldabraham@email.arizona.edu>
+ * @author Davide Pesavento <davidepesa@gmail.com>
  */
 
 #include "ndnpoke.hpp"
@@ -46,7 +47,7 @@
 {
   auto data = createData();
 
-  if (m_options.wantForceData) {
+  if (m_options.wantUnsolicited) {
     return sendData(*data);
   }
 
@@ -60,9 +61,7 @@
 NdnPoke::createData() const
 {
   auto data = make_shared<Data>(m_options.name);
-  if (m_options.freshnessPeriod) {
-    data->setFreshnessPeriod(*m_options.freshnessPeriod);
-  }
+  data->setFreshnessPeriod(m_options.freshnessPeriod);
   if (m_options.wantFinalBlockId) {
     data->setFinalBlock(m_options.name.at(-1));
   }
diff --git a/tools/peek/ndnpoke/ndnpoke.hpp b/tools/peek/ndnpoke/ndnpoke.hpp
index adab5eb..5ffd8cf 100644
--- a/tools/peek/ndnpoke/ndnpoke.hpp
+++ b/tools/peek/ndnpoke/ndnpoke.hpp
@@ -23,6 +23,7 @@
  * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
  *
  * @author Jerald Paul Abraham <jeraldabraham@email.arizona.edu>
+ * @author Davide Pesavento <davidepesa@gmail.com>
  */
 
 #ifndef NDN_TOOLS_NDNPOKE_NDNPOKE_HPP
@@ -42,13 +43,13 @@
 {
   // Data construction options
   Name name;
-  optional<time::milliseconds> freshnessPeriod;
+  time::milliseconds freshnessPeriod = DEFAULT_FRESHNESS_PERIOD;
   bool wantFinalBlockId = false;
   security::SigningInfo signingInfo;
 
   // program behavior options
   bool isVerbose = false;
-  bool wantForceData = false;
+  bool wantUnsolicited = false;
   optional<time::milliseconds> timeout;
 };