/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2011-2015  Regents of the University of California.
 *
 * This file is part of ndnSIM. See AUTHORS for complete list of ndnSIM authors and
 * contributors.
 *
 * ndnSIM 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.
 *
 * ndnSIM 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
 * ndnSIM, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
 **/

// Based on the code by Hajime Tazaki <tazaki@sfc.wide.ad.jp>

#include "annotated-topology-reader.hpp"

#include "ns3/nstime.h"
#include "ns3/log.h"
#include "ns3/assert.h"
#include "ns3/names.h"
#include "ns3/net-device-container.h"
#include "ns3/point-to-point-helper.h"
#include "ns3/point-to-point-net-device.h"
#include "ns3/internet-stack-helper.h"
#include "ns3/ipv4-address-helper.h"
#include "ns3/ipv4-global-routing-helper.h"
#include "ns3/drop-tail-queue.h"
#include "ns3/ipv4-interface.h"
#include "ns3/ipv4.h"
#include "ns3/string.h"
#include "ns3/pointer.h"
#include "ns3/uinteger.h"
#include "ns3/ipv4-address.h"
#include "ns3/random-variable.h"
#include "ns3/error-model.h"
#include "ns3/constant-position-mobility-model.h"

#include "model/ndn-l3-protocol.hpp"
#include "model/ndn-net-device-face.hpp"

#include <boost/foreach.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/tokenizer.hpp>

#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graphviz.hpp>

#include <set>

#ifdef NS3_MPI
#include <ns3/mpi-interface.h>
#endif

using namespace std;

namespace ns3 {

NS_LOG_COMPONENT_DEFINE("AnnotatedTopologyReader");

AnnotatedTopologyReader::AnnotatedTopologyReader(const std::string& path, double scale /*=1.0*/)
  : m_path(path)
  , m_randX(0, 100.0)
  , m_randY(0, 100.0)
  , m_scale(scale)
  , m_requiredPartitions(1)
{
  NS_LOG_FUNCTION(this);

  SetMobilityModel("ns3::ConstantPositionMobilityModel");
}

void
AnnotatedTopologyReader::SetBoundingBox(double ulx, double uly, double lrx, double lry)
{
  NS_LOG_FUNCTION(this << ulx << uly << lrx << lry);

  m_randX = UniformVariable(ulx, lrx);
  m_randY = UniformVariable(uly, lry);
}

void
AnnotatedTopologyReader::SetMobilityModel(const std::string& model)
{
  NS_LOG_FUNCTION(this << model);
  m_mobilityFactory.SetTypeId(model);
}

AnnotatedTopologyReader::~AnnotatedTopologyReader()
{
  NS_LOG_FUNCTION(this);
}

Ptr<Node>
AnnotatedTopologyReader::CreateNode(const std::string name, uint32_t systemId)
{
  NS_LOG_FUNCTION(this << name);
  m_requiredPartitions = std::max(m_requiredPartitions, systemId + 1);

  Ptr<Node> node = CreateObject<Node>(systemId);

  Names::Add(m_path, name, node);
  m_nodes.Add(node);

  return node;
}

Ptr<Node>
AnnotatedTopologyReader::CreateNode(const std::string name, double posX, double posY,
                                    uint32_t systemId)
{
  NS_LOG_FUNCTION(this << name << posX << posY);
  m_requiredPartitions = std::max(m_requiredPartitions, systemId + 1);

  Ptr<Node> node = CreateObject<Node>(systemId);
  Ptr<MobilityModel> loc = DynamicCast<MobilityModel>(m_mobilityFactory.Create());
  node->AggregateObject(loc);

  loc->SetPosition(Vector(posX, posY, 0));

  Names::Add(m_path, name, node);
  m_nodes.Add(node);

  return node;
}

NodeContainer
AnnotatedTopologyReader::GetNodes() const
{
  return m_nodes;
}

const std::list<TopologyReader::Link>&
AnnotatedTopologyReader::GetLinks() const
{
  return m_linksList;
}

NodeContainer
AnnotatedTopologyReader::Read(void)
{
  ifstream topgen;
  topgen.open(GetFileName().c_str());

  if (!topgen.is_open() || !topgen.good()) {
    NS_FATAL_ERROR("Cannot open file " << GetFileName() << " for reading");
    return m_nodes;
  }

  while (!topgen.eof()) {
    string line;
    getline(topgen, line);

    if (line == "router")
      break;
  }

  if (topgen.eof()) {
    NS_FATAL_ERROR("Topology file " << GetFileName() << " does not have \"router\" section");
    return m_nodes;
  }

  while (!topgen.eof()) {
    string line;
    getline(topgen, line);
    if (line[0] == '#')
      continue; // comments
    if (line == "link")
      break; // stop reading nodes

    istringstream lineBuffer(line);
    string name, city;
    double latitude = 0, longitude = 0;
    uint32_t systemId = 0;

    lineBuffer >> name >> city >> latitude >> longitude >> systemId;
    if (name.empty())
      continue;

    Ptr<Node> node;

    if (abs(latitude) > 0.001 && abs(latitude) > 0.001)
      node = CreateNode(name, m_scale * longitude, -m_scale * latitude, systemId);
    else {
      UniformVariable var(0, 200);
      node = CreateNode(name, var.GetValue(), var.GetValue(), systemId);
      // node = CreateNode (name, systemId);
    }
  }

  map<string, set<string>> processedLinks; // to eliminate duplications

  if (topgen.eof()) {
    NS_LOG_ERROR("Topology file " << GetFileName() << " does not have \"link\" section");
    return m_nodes;
  }

  // SeekToSection ("link");
  while (!topgen.eof()) {
    string line;
    getline(topgen, line);
    if (line == "")
      continue;
    if (line[0] == '#')
      continue; // comments

    // NS_LOG_DEBUG ("Input: [" << line << "]");

    istringstream lineBuffer(line);
    string from, to, capacity, metric, delay, maxPackets, lossRate;

    lineBuffer >> from >> to >> capacity >> metric >> delay >> maxPackets >> lossRate;

    if (processedLinks[to].size() != 0
        && processedLinks[to].find(from) != processedLinks[to].end()) {
      continue; // duplicated link
    }
    processedLinks[from].insert(to);

    Ptr<Node> fromNode = Names::Find<Node>(m_path, from);
    NS_ASSERT_MSG(fromNode != 0, from << " node not found");
    Ptr<Node> toNode = Names::Find<Node>(m_path, to);
    NS_ASSERT_MSG(toNode != 0, to << " node not found");

    Link link(fromNode, from, toNode, to);

    link.SetAttribute("DataRate", capacity);
    link.SetAttribute("OSPF", metric);

    if (!delay.empty())
      link.SetAttribute("Delay", delay);
    if (!maxPackets.empty())
      link.SetAttribute("MaxPackets", maxPackets);

    // Saran Added lossRate
    if (!lossRate.empty())
      link.SetAttribute("LossRate", lossRate);

    AddLink(link);
    NS_LOG_DEBUG("New link " << from << " <==> " << to << " / " << capacity << " with " << metric
                             << " metric (" << delay << ", " << maxPackets << ", " << lossRate
                             << ")");
  }

  NS_LOG_INFO("Annotated topology created with " << m_nodes.GetN() << " nodes and " << LinksSize()
                                                 << " links");
  topgen.close();

  ApplySettings();

  return m_nodes;
}

void
AnnotatedTopologyReader::AssignIpv4Addresses(Ipv4Address base)
{
  Ipv4AddressHelper address(base, Ipv4Mask("/24"));

  BOOST_FOREACH (const Link& link, m_linksList) {
    address.Assign(NetDeviceContainer(link.GetFromNetDevice(), link.GetToNetDevice()));

    base = Ipv4Address(base.Get() + 256);
    address.SetBase(base, Ipv4Mask("/24"));
  }
}

void
AnnotatedTopologyReader::ApplyOspfMetric()
{
  BOOST_FOREACH (const Link& link, m_linksList) {
    NS_LOG_DEBUG("OSPF: " << link.GetAttribute("OSPF"));
    uint16_t metric = boost::lexical_cast<uint16_t>(link.GetAttribute("OSPF"));

    {
      Ptr<Ipv4> ipv4 = link.GetFromNode()->GetObject<Ipv4>();
      if (ipv4 != 0) {
        int32_t interfaceId = ipv4->GetInterfaceForDevice(link.GetFromNetDevice());
        NS_ASSERT(interfaceId >= 0);

        ipv4->SetMetric(interfaceId, metric);
      }

      Ptr<ndn::L3Protocol> ndn = link.GetFromNode()->GetObject<ndn::L3Protocol>();
      if (ndn != 0) {
        shared_ptr<ndn::Face> face = ndn->getFaceByNetDevice(link.GetFromNetDevice());
        NS_ASSERT(face != 0);

        face->setMetric(metric);
      }
    }

    {
      Ptr<Ipv4> ipv4 = link.GetToNode()->GetObject<Ipv4>();
      if (ipv4 != 0) {
        int32_t interfaceId = ipv4->GetInterfaceForDevice(link.GetToNetDevice());
        NS_ASSERT(interfaceId >= 0);

        ipv4->SetMetric(interfaceId, metric);
      }

      Ptr<ndn::L3Protocol> ndn = link.GetToNode()->GetObject<ndn::L3Protocol>();
      if (ndn != 0) {
        shared_ptr<ndn::Face> face = ndn->getFaceByNetDevice(link.GetToNetDevice());
        NS_ASSERT(face != 0);

        face->setMetric(metric);
      }
    }
  }
}

void
AnnotatedTopologyReader::ApplySettings()
{
#ifdef NS3_MPI
  if (MpiInterface::IsEnabled() && MpiInterface::GetSize() != m_requiredPartitions) {
    std::cerr << "MPI interface is enabled, but number of partitions (" << MpiInterface::GetSize()
              << ") is not equal to number of partitions in the topology (" << m_requiredPartitions
              << ")";
    exit(-1);
  }
#endif

  PointToPointHelper p2p;

  BOOST_FOREACH (Link& link, m_linksList) {
    // cout << "Link: " << Findlink.GetFromNode () << ", " << link.GetToNode () << endl;
    string tmp;

    ////////////////////////////////////////////////
    if (link.GetAttributeFailSafe("MaxPackets", tmp)) {
      NS_LOG_INFO("MaxPackets = " + link.GetAttribute("MaxPackets"));

      try {
        uint32_t maxPackets = boost::lexical_cast<uint32_t>(link.GetAttribute("MaxPackets"));

        // compatibility mode. Only DropTailQueue is supported
        p2p.SetQueue("ns3::DropTailQueue", "MaxPackets", UintegerValue(maxPackets));
      }
      catch (...) {
        typedef boost::tokenizer<boost::escaped_list_separator<char>> tokenizer;
        std::string value = link.GetAttribute("MaxPackets");
        tokenizer tok(value);

        tokenizer::iterator token = tok.begin();
        p2p.SetQueue(*token);

        for (token++; token != tok.end(); token++) {
          boost::escaped_list_separator<char> separator('\\', '=', '\"');
          tokenizer attributeTok(*token, separator);

          tokenizer::iterator attributeToken = attributeTok.begin();

          string attribute = *attributeToken;
          attributeToken++;

          if (attributeToken == attributeTok.end()) {
            NS_LOG_ERROR("Queue attribute [" << *token
                                             << "] should be in form <Attribute>=<Value>");
            continue;
          }

          string value = *attributeToken;

          p2p.SetQueueAttribute(attribute, StringValue(value));
        }
      }
    }

    if (link.GetAttributeFailSafe("DataRate", tmp)) {
      NS_LOG_INFO("DataRate = " + link.GetAttribute("DataRate"));
      p2p.SetDeviceAttribute("DataRate", StringValue(link.GetAttribute("DataRate")));
    }

    if (link.GetAttributeFailSafe("Delay", tmp)) {
      NS_LOG_INFO("Delay = " + link.GetAttribute("Delay"));
      p2p.SetChannelAttribute("Delay", StringValue(link.GetAttribute("Delay")));
    }

    NetDeviceContainer nd = p2p.Install(link.GetFromNode(), link.GetToNode());
    link.SetNetDevices(nd.Get(0), nd.Get(1));

    ////////////////////////////////////////////////
    if (link.GetAttributeFailSafe("LossRate", tmp)) {
      NS_LOG_INFO("LinkError = " + link.GetAttribute("LossRate"));

      typedef boost::tokenizer<boost::escaped_list_separator<char>> tokenizer;
      std::string value = link.GetAttribute("LossRate");
      tokenizer tok(value);

      tokenizer::iterator token = tok.begin();
      ObjectFactory factory(*token);

      for (token++; token != tok.end(); token++) {
        boost::escaped_list_separator<char> separator('\\', '=', '\"');
        tokenizer attributeTok(*token, separator);

        tokenizer::iterator attributeToken = attributeTok.begin();

        string attribute = *attributeToken;
        attributeToken++;

        if (attributeToken == attributeTok.end()) {
          NS_LOG_ERROR("ErrorModel attribute [" << *token
                                                << "] should be in form <Attribute>=<Value>");
          continue;
        }

        string value = *attributeToken;

        factory.Set(attribute, StringValue(value));
      }

      nd.Get(0)->SetAttribute("ReceiveErrorModel", PointerValue(factory.Create<ErrorModel>()));
      nd.Get(1)->SetAttribute("ReceiveErrorModel", PointerValue(factory.Create<ErrorModel>()));
    }
  }
}

void
AnnotatedTopologyReader::SaveTopology(const std::string& file)
{
  ofstream os(file.c_str(), ios::trunc);
  os << "# any empty lines and lines starting with '#' symbol is ignored\n"
     << "\n"
     << "# The file should contain exactly two sections: router and link, each starting with the "
        "corresponding keyword\n"
     << "\n"
     << "# router section defines topology nodes and their relative positions (e.g., to use in "
        "visualizer)\n"
     << "router\n"
     << "\n"
     << "# each line in this section represents one router and should have the following data\n"
     << "# node  comment     yPos    xPos\n";

  for (NodeContainer::Iterator node = m_nodes.Begin(); node != m_nodes.End(); node++) {
    std::string name = Names::FindName(*node);
    Ptr<MobilityModel> mobility = (*node)->GetObject<MobilityModel>();
    Vector position = mobility->GetPosition();

    os << name << "\t"
       << "NA"
       << "\t" << -position.y << "\t" << position.x << "\n";
  }

  os
    << "# link section defines point-to-point links between nodes and characteristics of these "
       "links\n"
    << "\n"
    << "link\n"
    << "\n"
    << "# Each line should be in the following format (only first two are required, the rest can "
       "be omitted)\n"
    << "# srcNode   dstNode     bandwidth   metric  delay   queue\n"
    << "# bandwidth: link bandwidth\n"
    << "# metric: routing metric\n"
    << "# delay:  link delay\n"
    << "# queue:  MaxPackets for transmission queue on the link (both directions)\n"
    << "# error:  comma-separated list, specifying class for ErrorModel and necessary attributes\n";

  for (std::list<Link>::const_iterator link = m_linksList.begin(); link != m_linksList.end();
       link++) {
    os << Names::FindName(link->GetFromNode()) << "\t";
    os << Names::FindName(link->GetToNode()) << "\t";

    string tmp;
    if (link->GetAttributeFailSafe("DataRate", tmp))
      os << link->GetAttribute("DataRate") << "\t";
    else
      NS_FATAL_ERROR("DataRate must be specified for the link");

    if (link->GetAttributeFailSafe("OSPF", tmp))
      os << link->GetAttribute("OSPF") << "\t";
    else
      os << "1\t";

    if (link->GetAttributeFailSafe("Delay", tmp)) {
      os << link->GetAttribute("Delay") << "\t";

      if (link->GetAttributeFailSafe("MaxPackets", tmp)) {
        os << link->GetAttribute("MaxPackets") << "\t";

        if (link->GetAttributeFailSafe("LossRate", tmp)) {
          os << link->GetAttribute("LossRate") << "\t";
        }
      }
    }
    os << "\n";
  }
}

template<class Names>
class name_writer {
public:
  name_writer(Names _names)
    : names(_names)
  {
  }

  template<class VertexOrEdge>
  void
  operator()(std::ostream& out, const VertexOrEdge& v) const
  {
    // out << "[label=\"" << names[v] << "\",style=filled,fillcolor=\"" << colors[v] << "\"]";
    out << "[shape=\"circle\",width=0.1,label=\"\",style=filled,fillcolor=\"green\"]";
  }

private:
  Names names;
};

template<class Names>
inline name_writer<Names>
make_name_writer(Names n)
{
  return name_writer<Names>(n);
}

void
AnnotatedTopologyReader::SaveGraphviz(const std::string& file)
{
  typedef boost::adjacency_list_traits<boost::setS, boost::setS, boost::undirectedS> Traits;

  typedef boost::property<boost::vertex_name_t, std::string,
                          boost::property<boost::vertex_index_t, uint32_t>> nodeProperty;

  typedef boost::no_property edgeProperty;

  typedef boost::adjacency_list<boost::setS, boost::setS, boost::undirectedS, nodeProperty,
                                edgeProperty> Graph;

  typedef map<string, Traits::vertex_descriptor> node_map_t;
  node_map_t graphNodes;
  Graph graph;

  for (NodeContainer::Iterator node = m_nodes.Begin(); node != m_nodes.End(); node++) {
    std::pair<node_map_t::iterator, bool> retval = graphNodes.insert(
      make_pair(Names::FindName(*node), add_vertex(nodeProperty(Names::FindName(*node)), graph)));
    // NS_ASSERT (ok == true);

    put(boost::vertex_index, graph, retval.first->second, (*node)->GetId());
  }

  for (std::list<Link>::const_iterator link = m_linksList.begin(); link != m_linksList.end();
       link++) {
    node_map_t::iterator from = graphNodes.find(Names::FindName(link->GetFromNode()));
    node_map_t::iterator to = graphNodes.find(Names::FindName(link->GetToNode()));

    // add_edge (node->second, otherNode->second, m_graph);
    boost::add_edge(from->second, to->second, graph);
  }

  ofstream of(file.c_str());
  boost::property_map<Graph, boost::vertex_name_t>::type names = get(boost::vertex_name, graph);
  write_graphviz(of, graph, make_name_writer(names));
}
}
