/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2014-2018,  The University of Memphis,
 *                           Regents of the University of California,
 *                           Arizona Board of Regents.
 *
 * This file is part of NLSR (Named-data Link State Routing).
 * See AUTHORS.md for complete list of NLSR authors and contributors.
 *
 * NLSR is free software: you can redistribute it and/or modify it under the terms
 * of the GNU General Public License as published by the Free Software Foundation,
 * either version 3 of the License, or (at your option) any later version.
 *
 * NLSR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 * PURPOSE.  See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * NLSR, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
 **/

#include "lsa.hpp"
#include "nlsr.hpp"
#include "name-prefix-list.hpp"
#include "adjacent.hpp"
#include "logger.hpp"

#include <string>
#include <iostream>
#include <sstream>
#include <algorithm>
#include <cmath>
#include <limits>
#include <boost/algorithm/string.hpp>

namespace nlsr {

INIT_LOGGER(Lsa);

std::string
Lsa::getData() const
{
  std::ostringstream os;
  os << m_origRouter << "|" << getType() << "|" << m_lsSeqNo << "|"
     << ndn::time::toIsoString(m_expirationTimePoint) << "|";
  return os.str();
}

const ndn::Name
Lsa::getKey() const
{
  return ndn::Name(m_origRouter).append(std::to_string(getType()));
}

bool
Lsa::deserializeCommon(boost::tokenizer<boost::char_separator<char>>::iterator& iterator)
{
  m_origRouter = ndn::Name(*iterator++);
  if (m_origRouter.size() <= 0)
    return false;
  if (*iterator++ != std::to_string(getType()))
    return false;
  m_lsSeqNo = boost::lexical_cast<uint32_t>(*iterator++);
  m_expirationTimePoint = ndn::time::fromIsoString(*iterator++);
  return true;
}

NameLsa::NameLsa(const ndn::Name& origR, uint32_t lsn,
                 const ndn::time::system_clock::TimePoint& lt,
                 NamePrefixList& npl)
{
  m_origRouter = origR;
  m_lsSeqNo = lsn;
  m_expirationTimePoint = lt;
  for (const auto& name : npl.getNames()) {
    addName(name);
  }
}

std::string
NameLsa::serialize() const
{
  std::ostringstream os;
  os << getData() << m_npl.size();
  for (const auto& name : m_npl.getNames()) {
    os << "|" << name;
  }
  os << "|";
  return os.str();
}

bool
NameLsa::deserialize(const std::string& content) noexcept
{
  uint32_t numName = 0;
  boost::char_separator<char> sep("|");
  boost::tokenizer<boost::char_separator<char> >tokens(content, sep);
  boost::tokenizer<boost::char_separator<char> >::iterator tok_iter =
                                               tokens.begin();

  try {
    if (!deserializeCommon(tok_iter))
      return false;
    numName = boost::lexical_cast<uint32_t>(*tok_iter++);
    for (uint32_t i = 0; i < numName; i++) {
      ndn::Name name(*tok_iter++);
      addName(name);
    }
  }
  catch (const std::exception& e) {
    NLSR_LOG_ERROR("Could not deserialize from content: " << e.what());
    return false;
  }
  return true;
}

bool
NameLsa::isEqualContent(const NameLsa& other) const
{
  return m_npl == other.getNpl();
}

void
NameLsa::writeLog() const
{
  NLSR_LOG_DEBUG(*this);
}

CoordinateLsa::CoordinateLsa(const ndn::Name& origR, uint32_t lsn,
                             const ndn::time::system_clock::TimePoint& lt,
                             double r, std::vector<double> theta)
{
  m_origRouter = origR;
  m_lsSeqNo = lsn;
  m_expirationTimePoint = lt;
  m_corRad = r;
  m_angles = theta;
}

bool
CoordinateLsa::isEqualContent(const CoordinateLsa& clsa)
{
  if (clsa.getCorTheta().size() != m_angles.size()) {
    return false;
  }

  std::vector<double> m_angles2 = clsa.getCorTheta();
  for (unsigned int i = 0; i < clsa.getCorTheta().size(); i++) {
    if (std::abs(m_angles[i] - m_angles2[i]) > std::numeric_limits<double>::epsilon()) {
      return false;
    }
  }

  return (std::abs(m_corRad - clsa.getCorRadius()) <
          std::numeric_limits<double>::epsilon());
}

std::string
CoordinateLsa::serialize() const
{
  std::ostringstream os;
  os << getData() << m_corRad << "|" << m_angles.size() << "|";
  for (const auto& angle: m_angles) {
    os << angle << "|";
  }
  return os.str();
}

bool
CoordinateLsa::deserialize(const std::string& content) noexcept
{
  boost::char_separator<char> sep("|");
  boost::tokenizer<boost::char_separator<char> >tokens(content, sep);
  boost::tokenizer<boost::char_separator<char> >::iterator tok_iter =
                                               tokens.begin();

  try {
    if (!deserializeCommon(tok_iter))
      return false;
    m_corRad = boost::lexical_cast<double>(*tok_iter++);
    int numAngles = boost::lexical_cast<uint32_t>(*tok_iter++);
    for (int i = 0; i < numAngles; i++) {
      m_angles.push_back(boost::lexical_cast<double>(*tok_iter++));
    }
  }
  catch (const std::exception& e) {
    NLSR_LOG_ERROR("Could not deserialize from content: " << e.what());
    return false;
  }
  return true;
}

void
CoordinateLsa::writeLog() const
{
  NLSR_LOG_DEBUG(*this);
}

AdjLsa::AdjLsa(const ndn::Name& origR, uint32_t lsn,
               const ndn::time::system_clock::TimePoint& lt,
               uint32_t nl , AdjacencyList& adl)
{
  m_origRouter = origR;
  m_lsSeqNo = lsn;
  m_expirationTimePoint = lt;
  m_noLink = nl;
  std::list<Adjacent> al = adl.getAdjList();
  for (std::list<Adjacent>::iterator it = al.begin(); it != al.end(); it++) {
    if (it->getStatus() == Adjacent::STATUS_ACTIVE) {
      addAdjacent((*it));
    }
  }
}

bool
AdjLsa::isEqualContent(AdjLsa& alsa)
{
  return m_adl == alsa.getAdl();
}

std::string
AdjLsa::serialize() const
{
  std::ostringstream os;
  os << getData() << m_adl.size();
  for (const auto& adjacent : m_adl.getAdjList()) {
    os << "|" << adjacent.getName() << "|" << adjacent.getFaceUri()
       << "|" << adjacent.getLinkCost();
  }
  os << "|";
  return os.str();
}

bool
AdjLsa::deserialize(const std::string& content) noexcept
{
  uint32_t numLink = 0;
  boost::char_separator<char> sep("|");
  boost::tokenizer<boost::char_separator<char> >tokens(content, sep);
  boost::tokenizer<boost::char_separator<char> >::iterator tok_iter =
                                               tokens.begin();

  try {
    if (!deserializeCommon(tok_iter))
      return false;
    numLink = boost::lexical_cast<uint32_t>(*tok_iter++);
    for (uint32_t i = 0; i < numLink; i++) {
      ndn::Name adjName(*tok_iter++);
      std::string connectingFaceUri(*tok_iter++);
      double linkCost = boost::lexical_cast<double>(*tok_iter++);
      Adjacent adjacent(adjName, ndn::FaceUri(connectingFaceUri), linkCost,
                        Adjacent::STATUS_INACTIVE, 0, 0);
      addAdjacent(adjacent);
    }
  }
  catch (const std::exception& e) {
    NLSR_LOG_ERROR("Could not deserialize from content: " << e.what());
    return false;
  }
  return true;
}

void
AdjLsa::addNptEntries(Nlsr& pnlsr)
{
  // Only add NPT entries if this is an adj LSA from another router.
  if (getOrigRouter() != pnlsr.getConfParameter().getRouterPrefix()) {
    // Pass the originating router as both the name to register and
    // where it came from.
    pnlsr.getNamePrefixTable().addEntry(getOrigRouter(), getOrigRouter());
  }
}


void
AdjLsa::removeNptEntries(Nlsr& pnlsr)
{
  if (getOrigRouter() != pnlsr.getConfParameter().getRouterPrefix()) {
    pnlsr.getNamePrefixTable().removeEntry(getOrigRouter(), getOrigRouter());
  }
}

void
AdjLsa::writeLog() const
{
  NLSR_LOG_DEBUG(*this);
}

std::ostream&
operator<<(std::ostream& os, const AdjLsa& lsa)
{
  os << lsa.toString();
  os << "-Adjacents:";

  int adjacencyIndex = 1;

  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";

  return os;
}

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);
  return os;
}

std::istream&
operator>>(std::istream& is, Lsa::Type& type)
{
  std::string typeString;
  is >> typeString;
  if (typeString == "ADJACENCY") {
    type = Lsa::Type::ADJACENCY;
  }
  else if (typeString == "COORDINATE") {
    type = Lsa::Type::COORDINATE;
  }
  else if (typeString == "NAME") {
    type = Lsa::Type::NAME;
  }
  else {
    type = Lsa::Type::BASE;
  }
  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 {
std::string
to_string(const nlsr::Lsa::Type& type)
{
  switch (type) {
  case nlsr::Lsa::Type::ADJACENCY:
     return "ADJACENCY";
  case nlsr::Lsa::Type::COORDINATE:
    return "COORDINATE";
  case nlsr::Lsa::Type::NAME:
    return "NAME";
  case nlsr::Lsa::Type::MOCK:
    return "MOCK";
  default:
    return "BASE";
  }
}

} // namespace std
