/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2011-2013 University of California, Los Angeles
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation;
 *
 * This program 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 this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
 *         Ilya Moiseenko <iliamo@cs.ucla.edu>
 */

#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;
        tokenizer tok(link.GetAttribute("MaxPackets"));

        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;
      tokenizer tok(link.GetAttribute("LossRate"));

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