lsa: improved printing and logging

refs: #4354

Change-Id: I27cc99c6d01ba22668f4f56ad57b6f34f24f8af2
diff --git a/src/lsa.cpp b/src/lsa.cpp
index 45cd33e..8b389f0 100644
--- a/src/lsa.cpp
+++ b/src/lsa.cpp
@@ -121,21 +121,9 @@
 }
 
 void
-NameLsa::writeLog()
+NameLsa::writeLog() const
 {
-  NLSR_LOG_DEBUG("Name Lsa: ");
-  NLSR_LOG_DEBUG("  Origination Router: " << m_origRouter);
-  NLSR_LOG_DEBUG("  Ls Type: " << getType());
-  NLSR_LOG_DEBUG("  Ls Seq No: " << m_lsSeqNo);
-  NLSR_LOG_DEBUG("  Ls Lifetime: " << m_expirationTimePoint);
-  NLSR_LOG_DEBUG("  Names: ");
-  int i = 1;
-  std::list<ndn::Name> nl = m_npl.getNames();
-  for (std::list<ndn::Name>::iterator it = nl.begin(); it != nl.end(); it++)
-  {
-    NLSR_LOG_DEBUG("    Name " << i << ": " << (*it));
-  }
-  NLSR_LOG_DEBUG("name_lsa_end");
+  NLSR_LOG_DEBUG(*this);
 }
 
 CoordinateLsa::CoordinateLsa(const ndn::Name& origR, uint32_t lsn,
@@ -203,18 +191,9 @@
 }
 
 void
-CoordinateLsa::writeLog()
+CoordinateLsa::writeLog() const
 {
-  NLSR_LOG_DEBUG("Cor Lsa: ");
-  NLSR_LOG_DEBUG("  Origination Router: " << m_origRouter);
-  NLSR_LOG_DEBUG("  Ls Type: " << getType());
-  NLSR_LOG_DEBUG("  Ls Seq No: " << m_lsSeqNo);
-  NLSR_LOG_DEBUG("  Ls Lifetime: " << m_expirationTimePoint);
-  NLSR_LOG_DEBUG("    Hyperbolic Radius: " << m_corRad);
-  int i = 0;
-  for(auto const& value: m_angles) {
-    NLSR_LOG_DEBUG("    Hyperbolic Theta " << i++ << ": "<< value);
-  }
+  NLSR_LOG_DEBUG(*this);
 }
 
 AdjLsa::AdjLsa(const ndn::Name& origR, uint32_t lsn,
@@ -302,28 +281,24 @@
 }
 
 void
-AdjLsa::writeLog()
+AdjLsa::writeLog() const
 {
   NLSR_LOG_DEBUG(*this);
 }
 
 std::ostream&
-operator<<(std::ostream& os, const AdjLsa& adjLsa)
+operator<<(std::ostream& os, const AdjLsa& lsa)
 {
-  os << "Adj Lsa:\n"
-     << "  Origination Router: " << adjLsa.getOrigRouter() << "\n"
-     << "  Ls Type: " << adjLsa.getType() << "\n"
-     << "  Ls Seq No: " << adjLsa.getLsSeqNo() << "\n"
-     << "  Ls Lifetime: " << adjLsa.getExpirationTimePoint() << "\n"
-     << "  Adjacents: \n";
+  os << lsa.toString();
+  os << "-Adjacents:";
 
   int adjacencyIndex = 1;
 
-  for (const Adjacent& adjacency : adjLsa) {
-  os << "    Adjacent " << adjacencyIndex++ << ":\n"
-     << "      Adjacent Name: " << adjacency.getName() << "\n"
-     << "      Connecting FaceUri: " << adjacency.getFaceUri() << "\n"
-     << "      Link Cost: " << adjacency.getLinkCost() << "\n";
+  for (const Adjacent& adjacency : lsa.m_adl) {
+  os << "--Adjacent" << adjacencyIndex++ << ":\n"
+     << "---Adjacent Name: " << adjacency.getName() << "\n"
+     << "---Connecting FaceUri: " << adjacency.getFaceUri() << "\n"
+     << "---Link Cost: " << adjacency.getLinkCost() << "\n";
   }
   os << "adj_lsa_end";
 
@@ -331,6 +306,35 @@
 }
 
 std::ostream&
+operator<<(std::ostream& os, const CoordinateLsa& lsa)
+{
+  os << lsa.toString();
+  os << "--Hyperbolic Radius: " << lsa.m_corRad << "\n";
+  int i = 0;
+  for (const auto& value : lsa.m_angles) {
+    os << "---Hyperbolic Theta: " << i++ << ": " << value << "\n";
+  }
+  os << "cor_lsa_end";
+
+  return os;
+}
+
+std::ostream&
+operator<<(std::ostream& os, const NameLsa& lsa)
+{
+  os << lsa.toString();
+  os << "--Names:\n";
+  int i = 0;
+  auto names = lsa.m_npl.getNames();
+  for (const auto& name : names) {
+    os << "---Name " << i++ << ": " << name << "\n";
+  }
+  os << "name_lsa_end";
+
+  return os;
+}
+
+std::ostream&
 operator<<(std::ostream& os, const Lsa::Type& type)
 {
   os << std::to_string(type);
@@ -357,6 +361,16 @@
   return is;
 }
 
+std::string
+Lsa::toString() const
+{
+  std::ostringstream os;
+  os << "LSA of type " << getType() << ":\n-Origin Router: " << getOrigRouter()
+     << "\n-Sequence Number: " << getLsSeqNo() << "\n-Expiration Point: "
+     << getExpirationTimePoint() << "\n";
+  return os.str();
+}
+
 } // namespace nlsr
 
 namespace std {
diff --git a/src/lsa.hpp b/src/lsa.hpp
index b2e0900..859a11b 100644
--- a/src/lsa.hpp
+++ b/src/lsa.hpp
@@ -123,6 +123,9 @@
   virtual bool
   deserialize(const std::string& content) = 0;
 
+  virtual void
+  writeLog() const = 0;
+
 protected:
   /*! Get data common to all LSA types.
 
@@ -132,6 +135,11 @@
   std::string
   getData() const;
 
+  /*! Print data common to all LSA types.
+   */
+  std::string
+  toString() const;
+
   bool
   deserializeCommon(boost::tokenizer<boost::char_separator<char>>::iterator& iterator);
 
@@ -198,7 +206,7 @@
   isEqualContent(const NameLsa& other) const;
 
   void
-  writeLog();
+  writeLog() const override;
 
   /*! \brief Returns the data that this name LSA has.
 
@@ -211,6 +219,9 @@
 
 private:
   NamePrefixList m_npl;
+
+  friend std::ostream&
+  operator<<(std::ostream& os, const NameLsa& lsa);
 };
 
 class AdjLsa: public Lsa
@@ -279,7 +290,7 @@
   removeNptEntries(Nlsr& pnlsr);
 
   void
-  writeLog();
+  writeLog() const override;
 
   const_iterator
   begin() const
@@ -306,6 +317,9 @@
 private:
   uint32_t m_noLink;
   AdjacencyList m_adl;
+
+  friend std::ostream&
+  operator<<(std::ostream& os, const AdjLsa& lsa);
 };
 
 class CoordinateLsa: public Lsa
@@ -365,7 +379,7 @@
   isEqualContent(const CoordinateLsa& clsa);
 
   void
-  writeLog();
+  writeLog() const override;
 
   /*! \brief Returns the data that this coordinate LSA represents.
 
@@ -378,10 +392,19 @@
 private:
   double m_corRad;
   std::vector<double> m_angles;
+
+  friend std::ostream&
+  operator<<(std::ostream& os, const CoordinateLsa& lsa);
 };
 
 std::ostream&
-operator<<(std::ostream& os, const AdjLsa& adjLsa);
+operator<<(std::ostream& os, const AdjLsa& lsa);
+
+std::ostream&
+operator<<(std::ostream& os, const CoordinateLsa& lsa);
+
+std::ostream&
+operator<<(std::ostream& os, const NameLsa& lsa);
 
 std::ostream&
 operator<<(std::ostream& os, const Lsa::Type& type);
diff --git a/tests/mocks/lsa.cpp b/tests/mocks/lsa.cpp
index 3ab6689..d9548a0 100644
--- a/tests/mocks/lsa.cpp
+++ b/tests/mocks/lsa.cpp
@@ -47,5 +47,10 @@
   return true;
 }
 
+void
+MockLsa::writeLog() const
+{
+}
+
 } // namespace test
 } // namespace nlsr
diff --git a/tests/mocks/lsa.hpp b/tests/mocks/lsa.hpp
index 0ce6e3a..5011ab4 100644
--- a/tests/mocks/lsa.hpp
+++ b/tests/mocks/lsa.hpp
@@ -43,6 +43,9 @@
 
   bool
   deserialize(const std::string& content) override;
+
+  void
+  writeLog() const override;
 };
 
 } // namespace test
diff --git a/tests/test-lsa.cpp b/tests/test-lsa.cpp
index 413e393..c5b3ffd 100644
--- a/tests/test-lsa.cpp
+++ b/tests/test-lsa.cpp
@@ -130,21 +130,19 @@
   AdjLsa lsa("router1", 12, testTimePoint, adjList.size(), adjList);
 
   std::string EXPECTED_OUTPUT =
-   "Adj Lsa:\n"
-   "  Origination Router: /router1\n"
-   "  Ls Type: ADJACENCY\n"
-   "  Ls Seq No: 12\n"
-   "  Ls Lifetime: " + TEST_TIME_POINT_STRING + "\n"
-   "  Adjacents: \n"
-   "    Adjacent 1:\n"
-   "      Adjacent Name: /adjacent1\n"
-   "      Connecting FaceUri: ://\n"
-   "      Link Cost: 10\n"
-   "    Adjacent 2:\n"
-   "      Adjacent Name: /adjacent2\n"
-   "      Connecting FaceUri: ://\n"
-   "      Link Cost: 10\n"
-   "adj_lsa_end";
+    "LSA of type ADJACENCY:\n"
+    "-Origin Router: /router1\n"
+    "-Sequence Number: 12\n"
+    "-Expiration Point: " + TEST_TIME_POINT_STRING + "\n"
+    "-Adjacents:--Adjacent1:\n"
+    "---Adjacent Name: /adjacent1\n"
+    "---Connecting FaceUri: ://\n"
+    "---Link Cost: 10\n"
+    "--Adjacent2:\n"
+    "---Adjacent Name: /adjacent2\n"
+    "---Connecting FaceUri: ://\n"
+    "---Link Cost: 10\n"
+    "adj_lsa_end";
 
   std::ostringstream os;
   os << lsa;