/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
/*
 * Copyright (c) 2011 UCLA
 *
 * 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>
 */

#if __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-variable"
#pragma clang diagnostic ignored "-Wunneeded-internal-declaration"
#endif

#include "ndn-global-routing-helper.hpp"

#include "ns3/ndn-l3-protocol.hpp"
#include "../model/ndn-net-device-face.hpp"
#include "../model/ndn-global-router.hpp"
#include "ns3/ndn-fib.hpp"

#include "ns3/node.h"
#include "ns3/node-container.h"
#include "ns3/net-device.h"
#include "ns3/channel.h"
#include "ns3/log.h"
#include "ns3/assert.h"
#include "ns3/names.h"
#include "ns3/node-list.h"
#include "ns3/channel-list.h"
#include "ns3/object-factory.h"

#include <boost/lexical_cast.hpp>
#include <boost/foreach.hpp>
#include <boost/concept/assert.hpp>
// #include <boost/graph/graph_concepts.hpp>
// #include <boost/graph/adjacency_list.hpp>
#include <boost/graph/dijkstra_shortest_paths.hpp>

#include "boost-graph-ndn-global-routing-helper.hpp"

#include <math.h>

NS_LOG_COMPONENT_DEFINE("ndn.GlobalRoutingHelper");

using namespace std;
using namespace boost;

namespace ns3 {
namespace ndn {

void
GlobalRoutingHelper::Install(Ptr<Node> node)
{
  NS_LOG_LOGIC("Node: " << node->GetId());

  Ptr<L3Protocol> ndn = node->GetObject<L3Protocol>();
  NS_ASSERT_MSG(ndn != 0, "Cannot install GlobalRoutingHelper before Ndn is installed on a node");

  Ptr<GlobalRouter> gr = node->GetObject<GlobalRouter>();
  if (gr != 0) {
    NS_LOG_DEBUG("GlobalRouter is already installed: " << gr);
    return; // already installed
  }

  gr = CreateObject<GlobalRouter>();
  node->AggregateObject(gr);

  for (uint32_t faceId = 0; faceId < ndn->GetNFaces(); faceId++) {
    Ptr<NetDeviceFace> face = DynamicCast<NetDeviceFace>(ndn->GetFace(faceId));
    if (face == 0) {
      NS_LOG_DEBUG("Skipping non-netdevice face");
      continue;
    }

    Ptr<NetDevice> nd = face->GetNetDevice();
    if (nd == 0) {
      NS_LOG_DEBUG("Not a NetDevice associated with NetDeviceFace");
      continue;
    }

    Ptr<Channel> ch = nd->GetChannel();

    if (ch == 0) {
      NS_LOG_DEBUG("Channel is not associated with NetDevice");
      continue;
    }

    if (ch->GetNDevices() == 2) // e.g., point-to-point channel
    {
      for (uint32_t deviceId = 0; deviceId < ch->GetNDevices(); deviceId++) {
        Ptr<NetDevice> otherSide = ch->GetDevice(deviceId);
        if (nd == otherSide)
          continue;

        Ptr<Node> otherNode = otherSide->GetNode();
        NS_ASSERT(otherNode != 0);

        Ptr<GlobalRouter> otherGr = otherNode->GetObject<GlobalRouter>();
        if (otherGr == 0) {
          Install(otherNode);
        }
        otherGr = otherNode->GetObject<GlobalRouter>();
        NS_ASSERT(otherGr != 0);
        gr->AddIncidency(face, otherGr);
      }
    }
    else {
      Ptr<GlobalRouter> grChannel = ch->GetObject<GlobalRouter>();
      if (grChannel == 0) {
        Install(ch);
      }
      grChannel = ch->GetObject<GlobalRouter>();

      gr->AddIncidency(face, grChannel);
    }
  }
}

void
GlobalRoutingHelper::Install(Ptr<Channel> channel)
{
  NS_LOG_LOGIC("Channel: " << channel->GetId());

  Ptr<GlobalRouter> gr = channel->GetObject<GlobalRouter>();
  if (gr != 0)
    return;

  gr = CreateObject<GlobalRouter>();
  channel->AggregateObject(gr);

  for (uint32_t deviceId = 0; deviceId < channel->GetNDevices(); deviceId++) {
    Ptr<NetDevice> dev = channel->GetDevice(deviceId);

    Ptr<Node> node = dev->GetNode();
    NS_ASSERT(node != 0);

    Ptr<GlobalRouter> grOther = node->GetObject<GlobalRouter>();
    if (grOther == 0) {
      Install(node);
    }
    grOther = node->GetObject<GlobalRouter>();
    NS_ASSERT(grOther != 0);

    gr->AddIncidency(0, grOther);
  }
}

void
GlobalRoutingHelper::Install(const NodeContainer& nodes)
{
  for (NodeContainer::Iterator node = nodes.Begin(); node != nodes.End(); node++) {
    Install(*node);
  }
}

void
GlobalRoutingHelper::InstallAll()
{
  Install(NodeContainer::GetGlobal());
}

void
GlobalRoutingHelper::AddOrigin(const std::string& prefix, Ptr<Node> node)
{
  Ptr<GlobalRouter> gr = node->GetObject<GlobalRouter>();
  NS_ASSERT_MSG(gr != 0, "GlobalRouter is not installed on the node");

  auto name = make_shared<Name>(prefix);
  gr->AddLocalPrefix(name);
}

void
GlobalRoutingHelper::AddOrigins(const std::string& prefix, const NodeContainer& nodes)
{
  for (NodeContainer::Iterator node = nodes.Begin(); node != nodes.End(); node++) {
    AddOrigin(prefix, *node);
  }
}

void
GlobalRoutingHelper::AddOrigin(const std::string& prefix, const std::string& nodeName)
{
  Ptr<Node> node = Names::Find<Node>(nodeName);
  NS_ASSERT_MSG(node != 0, nodeName << "is not a Node");

  AddOrigin(prefix, node);
}

void
GlobalRoutingHelper::AddOriginsForAll()
{
  for (NodeList::Iterator node = NodeList::Begin(); node != NodeList::End(); node++) {
    Ptr<GlobalRouter> gr = (*node)->GetObject<GlobalRouter>();
    string name = Names::FindName(*node);

    if (gr != 0 && !name.empty()) {
      AddOrigin("/" + name, *node);
    }
  }
}

void
GlobalRoutingHelper::CalculateRoutes(bool invalidatedRoutes /* = true*/)
{
  /**
   * Implementation of route calculation is heavily based on Boost Graph Library
   * See http://www.boost.org/doc/libs/1_49_0/libs/graph/doc/table_of_contents.html for more details
   */

  BOOST_CONCEPT_ASSERT((VertexListGraphConcept<NdnGlobalRouterGraph>));
  BOOST_CONCEPT_ASSERT((IncidenceGraphConcept<NdnGlobalRouterGraph>));

  NdnGlobalRouterGraph graph;
  // typedef graph_traits < NdnGlobalRouterGraph >::vertex_descriptor vertex_descriptor;

  // For now we doing Dijkstra for every node.  Can be replaced with Bellman-Ford or Floyd-Warshall.
  // Other algorithms should be faster, but they need additional EdgeListGraph concept provided by
  // the graph, which
  // is not obviously how implement in an efficient manner
  for (NodeList::Iterator node = NodeList::Begin(); node != NodeList::End(); node++) {
    Ptr<GlobalRouter> source = (*node)->GetObject<GlobalRouter>();
    if (source == 0) {
      NS_LOG_DEBUG("Node " << (*node)->GetId() << " does not export GlobalRouter interface");
      continue;
    }

    DistancesMap distances;

    dijkstra_shortest_paths(graph, source,
                            // predecessor_map (boost::ref(predecessors))
                            // .
                            distance_map(boost::ref(distances))
                              .distance_inf(WeightInf)
                              .distance_zero(WeightZero)
                              .distance_compare(boost::WeightCompare())
                              .distance_combine(boost::WeightCombine()));

    // NS_LOG_DEBUG (predecessors.size () << ", " << distances.size ());

    Ptr<Fib> fib = source->GetObject<Fib>();
    if (invalidatedRoutes) {
      fib->InvalidateAll();
    }
    NS_ASSERT(fib != 0);

    NS_LOG_DEBUG("Reachability from Node: " << source->GetObject<Node>()->GetId());
    for (DistancesMap::iterator i = distances.begin(); i != distances.end(); i++) {
      if (i->first == source)
        continue;
      else {
        // cout << "  Node " << i->first->GetObject<Node> ()->GetId ();
        if (i->second.get<0>() == 0) {
          // cout << " is unreachable" << endl;
        }
        else {
          BOOST_FOREACH (const std::shared_ptr<const Name>& prefix, i->first->GetLocalPrefixes()) {
            NS_LOG_DEBUG(" prefix " << prefix << " reachable via face " << *i->second.get<0>()
                                    << " with distance " << i->second.get<1>() << " with delay "
                                    << i->second.get<2>());

            Ptr<fib::Entry> entry = fib->Add(prefix, i->second.get<0>(), i->second.get<1>());
            entry->SetRealDelayToProducer(i->second.get<0>(), Seconds(i->second.get<2>()));

            Ptr<Limits> faceLimits = i->second.get<0>()->GetObject<Limits>();

            Ptr<Limits> fibLimits = entry->GetObject<Limits>();
            if (fibLimits != 0) {
              // if it was created by the forwarding strategy via DidAddFibEntry event
              fibLimits->SetLimits(faceLimits->GetMaxRate(), 2 * i->second.get<2>() /*exact RTT*/);
              NS_LOG_DEBUG("Set limit for prefix "
                           << *prefix << " " << faceLimits->GetMaxRate() << " / "
                           << 2 * i->second.get<2>() << "s ("
                           << faceLimits->GetMaxRate() * 2 * i->second.get<2>() << ")");
            }
          }
        }
      }
    }
  }
}

void
GlobalRoutingHelper::CalculateAllPossibleRoutes(bool invalidatedRoutes /* = true*/)
{
  /**
   * Implementation of route calculation is heavily based on Boost Graph Library
   * See http://www.boost.org/doc/libs/1_49_0/libs/graph/doc/table_of_contents.html for more details
   */

  BOOST_CONCEPT_ASSERT((VertexListGraphConcept<NdnGlobalRouterGraph>));
  BOOST_CONCEPT_ASSERT((IncidenceGraphConcept<NdnGlobalRouterGraph>));

  NdnGlobalRouterGraph graph;
  // typedef graph_traits < NdnGlobalRouterGraph >::vertex_descriptor vertex_descriptor;

  // For now we doing Dijkstra for every node.  Can be replaced with Bellman-Ford or Floyd-Warshall.
  // Other algorithms should be faster, but they need additional EdgeListGraph concept provided by
  // the graph, which
  // is not obviously how implement in an efficient manner
  for (NodeList::Iterator node = NodeList::Begin(); node != NodeList::End(); node++) {
    Ptr<GlobalRouter> source = (*node)->GetObject<GlobalRouter>();
    if (source == 0) {
      NS_LOG_DEBUG("Node " << (*node)->GetId() << " does not export GlobalRouter interface");
      continue;
    }

    Ptr<Fib> fib = source->GetObject<Fib>();
    if (invalidatedRoutes) {
      fib->InvalidateAll();
    }
    NS_ASSERT(fib != 0);

    NS_LOG_DEBUG("===========");
    NS_LOG_DEBUG("Reachability from Node: " << source->GetObject<Node>()->GetId() << " ("
                                            << Names::FindName(source->GetObject<Node>()) << ")");

    Ptr<L3Protocol> l3 = source->GetObject<L3Protocol>();
    NS_ASSERT(l3 != 0);

    // remember interface statuses
    std::vector<uint16_t> originalMetric(l3->GetNFaces());
    for (uint32_t faceId = 0; faceId < l3->GetNFaces(); faceId++) {
      originalMetric[faceId] = l3->GetFace(faceId)->GetMetric();
      l3->GetFace(faceId)
        ->SetMetric(std::numeric_limits<uint16_t>::max()
                    - 1); // value std::numeric_limits<uint16_t>::max () MUST NOT be used (reserved)
    }

    for (uint32_t enabledFaceId = 0; enabledFaceId < l3->GetNFaces(); enabledFaceId++) {
      if (DynamicCast<ndn::NetDeviceFace>(l3->GetFace(enabledFaceId)) == 0)
        continue;

      // enabling only faceId
      l3->GetFace(enabledFaceId)->SetMetric(originalMetric[enabledFaceId]);

      DistancesMap distances;

      NS_LOG_DEBUG("-----------");

      dijkstra_shortest_paths(graph, source,
                              // predecessor_map (boost::ref(predecessors))
                              // .
                              distance_map(boost::ref(distances))
                                .distance_inf(WeightInf)
                                .distance_zero(WeightZero)
                                .distance_compare(boost::WeightCompare())
                                .distance_combine(boost::WeightCombine()));

      // NS_LOG_DEBUG (predecessors.size () << ", " << distances.size ());

      for (DistancesMap::iterator i = distances.begin(); i != distances.end(); i++) {
        if (i->first == source)
          continue;
        else {
          // cout << "  Node " << i->first->GetObject<Node> ()->GetId ();
          if (i->second.get<0>() == 0) {
            // cout << " is unreachable" << endl;
          }
          else {
            BOOST_FOREACH (const std::shared_ptr<const Name>& prefix,
                           i->first->GetLocalPrefixes()) {
              NS_LOG_DEBUG(" prefix " << *prefix << " reachable via face " << *i->second.get<0>()
                                      << " with distance " << i->second.get<1>() << " with delay "
                                      << i->second.get<2>());

              if (i->second.get<0>()->GetMetric() == std::numeric_limits<uint16_t>::max() - 1)
                continue;

              Ptr<fib::Entry> entry = fib->Add(prefix, i->second.get<0>(), i->second.get<1>());
              entry->SetRealDelayToProducer(i->second.get<0>(), Seconds(i->second.get<2>()));

              Ptr<Limits> faceLimits = i->second.get<0>()->GetObject<Limits>();

              Ptr<Limits> fibLimits = entry->GetObject<Limits>();
              if (fibLimits != 0) {
                // if it was created by the forwarding strategy via DidAddFibEntry event
                fibLimits->SetLimits(faceLimits->GetMaxRate(),
                                     2 * i->second.get<2>() /*exact RTT*/);
                NS_LOG_DEBUG("Set limit for prefix "
                             << *prefix << " " << faceLimits->GetMaxRate() << " / "
                             << 2 * i->second.get<2>() << "s ("
                             << faceLimits->GetMaxRate() * 2 * i->second.get<2>() << ")");
              }
            }
          }
        }
      }

      // disabling the face again
      l3->GetFace(enabledFaceId)->SetMetric(std::numeric_limits<uint16_t>::max() - 1);
    }

    // recover original interface statuses
    for (uint32_t faceId = 0; faceId < l3->GetNFaces(); faceId++) {
      l3->GetFace(faceId)->SetMetric(originalMetric[faceId]);
    }
  }
}

} // namespace ndn
} // namespace ns3
