face: Make default transport configurable

This commit also removes support for the ndnd-tlv-0.7
protocol's default socket location from UnixTransport.

Test HOME environment changing has also been centralized
into a single fixture (util/test-home-environment-fixture.hpp)

refs #2189

Change-Id: Iac1a6c88d7a2d9fcfb91a20356ac21b75daf7d17
diff --git a/src/face.cpp b/src/face.cpp
index 1db6371..8535924 100644
--- a/src/face.cpp
+++ b/src/face.cpp
@@ -28,6 +28,7 @@
 #include "security/key-chain.hpp"
 #include "util/time.hpp"
 #include "util/random.hpp"
+#include "util/face-uri.hpp"
 
 namespace ndn {
 
@@ -38,9 +39,7 @@
   , m_isDirectNfdFibManagementRequested(false)
   , m_impl(new Impl(*this))
 {
-  const std::string socketName = UnixTransport::getDefaultSocketName(m_impl->m_config);
-  construct(make_shared<UnixTransport>(socketName),
-            m_internalKeyChain);
+  construct(m_internalKeyChain);
 }
 
 Face::Face(boost::asio::io_service& ioService)
@@ -49,9 +48,7 @@
   , m_isDirectNfdFibManagementRequested(false)
   , m_impl(new Impl(*this))
 {
-  const std::string socketName = UnixTransport::getDefaultSocketName(m_impl->m_config);
-  construct(make_shared<UnixTransport>(socketName),
-            m_internalKeyChain);
+  construct(m_internalKeyChain);
 }
 
 Face::Face(const std::string& host, const std::string& port/* = "6363"*/)
@@ -99,6 +96,50 @@
 }
 
 void
+Face::construct(KeyChain* keyChain)
+{
+  // transport=unix:///var/run/nfd.sock
+  // transport=tcp://localhost:6363
+
+  const ConfigFile::Parsed& parsed = m_impl->m_config.getParsedConfiguration();
+
+  const auto transportType = parsed.get_optional<std::string>("transport");
+  if (!transportType)
+    {
+      // transport not specified, use default Unix transport.
+      construct(UnixTransport::create(m_impl->m_config), keyChain);
+      return;
+    }
+
+  unique_ptr<util::FaceUri> uri;
+  try
+    {
+      uri.reset(new util::FaceUri(*transportType));
+    }
+  catch (const util::FaceUri::Error& error)
+    {
+      throw ConfigFile::Error(error.what());
+    }
+
+  shared_ptr<Transport> transport;
+  const std::string protocol = uri->getScheme();
+
+  if (protocol == "unix")
+    {
+      construct(UnixTransport::create(m_impl->m_config), keyChain);
+
+    }
+  else if (protocol == "tcp" || protocol == "tcp4" || protocol == "tcp6")
+    {
+      construct(TcpTransport::create(m_impl->m_config), keyChain);
+    }
+  else
+    {
+      throw ConfigFile::Error("Unsupported transport protocol \"" + protocol + "\"");
+    }
+}
+
+void
 Face::construct(shared_ptr<Transport> transport,
                 KeyChain* keyChain)
 {
@@ -171,8 +212,8 @@
                       const OnData& onData, const OnTimeout& onTimeout/* = OnTimeout()*/)
 {
   return expressInterest(Interest(tmpl)
-                           .setName(name)
-                           .setNonce(0),
+                         .setName(name)
+                         .setNonce(0),
                          onData, onTimeout);
 }