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

#ifndef BOOST_GRAPH_NDN_GLOBAL_ROUTING_HELPER_H
#define BOOST_GRAPH_NDN_GLOBAL_ROUTING_HELPER_H

/// @cond include_hidden

#include <boost/graph/graph_traits.hpp>
#include <boost/graph/properties.hpp>
#include <boost/ref.hpp>

#include "ns3/ndn-face.hpp"
#include "ns3/ndn-limits.hpp"
#include "ns3/node-list.h"
#include "ns3/channel-list.h"
#include "../model/ndn-global-router.hpp"
#include <list>
#include <map>

namespace boost {

class NdnGlobalRouterGraph {
public:
  typedef ns3::Ptr<ns3::ndn::GlobalRouter> Vertice;
  typedef uint16_t edge_property_type;
  typedef uint32_t vertex_property_type;

  NdnGlobalRouterGraph()
  {
    for (ns3::NodeList::Iterator node = ns3::NodeList::Begin(); node != ns3::NodeList::End();
         node++) {
      ns3::Ptr<ns3::ndn::GlobalRouter> gr = (*node)->GetObject<ns3::ndn::GlobalRouter>();
      if (gr != 0)
        m_vertices.push_back(gr);
    }

    for (ns3::ChannelList::Iterator channel = ns3::ChannelList::Begin();
         channel != ns3::ChannelList::End(); channel++) {
      ns3::Ptr<ns3::ndn::GlobalRouter> gr = (*channel)->GetObject<ns3::ndn::GlobalRouter>();
      if (gr != 0)
        m_vertices.push_back(gr);
    }
  }

  const std::list<Vertice>&
  GetVertices() const
  {
    return m_vertices;
  }

public:
  std::list<Vertice> m_vertices;
};

class ndn_global_router_graph_category : public virtual vertex_list_graph_tag,
                                         public virtual incidence_graph_tag {
};

template<>
struct graph_traits<NdnGlobalRouterGraph> {
  // Graph concept
  typedef NdnGlobalRouterGraph::Vertice vertex_descriptor;
  typedef ns3::ndn::GlobalRouter::Incidency edge_descriptor;
  typedef directed_tag directed_category;
  typedef disallow_parallel_edge_tag edge_parallel_category;
  typedef ndn_global_router_graph_category traversal_category;

  // VertexList concept
  typedef std::list<vertex_descriptor>::const_iterator vertex_iterator;
  typedef size_t vertices_size_type;

  // AdjacencyGraph concept
  typedef ns3::ndn::GlobalRouter::IncidencyList::iterator out_edge_iterator;
  typedef size_t degree_size_type;

  // typedef size_t edges_size_type;
};

} // namespace boost

namespace boost {

inline graph_traits<NdnGlobalRouterGraph>::vertex_descriptor
source(graph_traits<NdnGlobalRouterGraph>::edge_descriptor e, const NdnGlobalRouterGraph& g)
{
  return e.get<0>();
}

inline graph_traits<NdnGlobalRouterGraph>::vertex_descriptor
target(graph_traits<NdnGlobalRouterGraph>::edge_descriptor e, const NdnGlobalRouterGraph& g)
{
  return e.get<2>();
}

inline std::pair<graph_traits<NdnGlobalRouterGraph>::vertex_iterator,
                 graph_traits<NdnGlobalRouterGraph>::vertex_iterator>
vertices(const NdnGlobalRouterGraph& g)
{
  return make_pair(g.GetVertices().begin(), g.GetVertices().end());
}

inline graph_traits<NdnGlobalRouterGraph>::vertices_size_type
num_vertices(const NdnGlobalRouterGraph& g)
{
  return g.GetVertices().size();
}

inline std::pair<graph_traits<NdnGlobalRouterGraph>::out_edge_iterator,
                 graph_traits<NdnGlobalRouterGraph>::out_edge_iterator>
out_edges(graph_traits<NdnGlobalRouterGraph>::vertex_descriptor u, const NdnGlobalRouterGraph& g)
{
  return std::make_pair(u->GetIncidencies().begin(), u->GetIncidencies().end());
}

inline graph_traits<NdnGlobalRouterGraph>::degree_size_type
out_degree(graph_traits<NdnGlobalRouterGraph>::vertex_descriptor u, const NdnGlobalRouterGraph& g)
{
  return u->GetIncidencies().size();
}

//////////////////////////////////////////////////////////////
// Property maps

struct EdgeWeights {
  EdgeWeights(const NdnGlobalRouterGraph& graph)
    : m_graph(graph)
  {
  }

private:
  const NdnGlobalRouterGraph& m_graph;
};

struct VertexIds {
  VertexIds(const NdnGlobalRouterGraph& graph)
    : m_graph(graph)
  {
  }

private:
  const NdnGlobalRouterGraph& m_graph;
};

template<>
struct property_map<NdnGlobalRouterGraph, edge_weight_t> {
  typedef const EdgeWeights const_type;
  typedef EdgeWeights type;
};

template<>
struct property_map<NdnGlobalRouterGraph, vertex_index_t> {
  typedef const VertexIds const_type;
  typedef VertexIds type;
};

template<>
struct property_traits<EdgeWeights> {
  // Metric property map
  typedef tuple<ns3::Ptr<ns3::ndn::Face>, uint16_t, double> value_type;
  typedef tuple<ns3::Ptr<ns3::ndn::Face>, uint16_t, double> reference;
  typedef ns3::ndn::GlobalRouter::Incidency key_type;
  typedef readable_property_map_tag category;
};

const property_traits<EdgeWeights>::value_type WeightZero(0, 0, 0.0);
const property_traits<EdgeWeights>::value_type
  WeightInf(0, std::numeric_limits<uint16_t>::max(), 0.0);

struct WeightCompare : public std::binary_function<property_traits<EdgeWeights>::reference,
                                                   property_traits<EdgeWeights>::reference, bool> {
  bool
  operator()(tuple<ns3::Ptr<ns3::ndn::Face>, uint32_t, double> a,
             tuple<ns3::Ptr<ns3::ndn::Face>, uint32_t, double> b) const
  {
    return a.get<1>() < b.get<1>();
  }

  bool
  operator()(property_traits<EdgeWeights>::reference a, uint32_t b) const
  {
    return a.get<1>() < b;
  }

  bool
  operator()(uint32_t a, uint32_t b) const
  {
    return a < b;
  }
};

struct WeightCombine
  : public std::binary_function<uint32_t, property_traits<EdgeWeights>::reference, uint32_t> {
  uint32_t
  operator()(uint32_t a, property_traits<EdgeWeights>::reference b) const
  {
    return a + b.get<1>();
  }

  tuple<ns3::Ptr<ns3::ndn::Face>, uint32_t, double>
  operator()(tuple<ns3::Ptr<ns3::ndn::Face>, uint32_t, double> a,
             property_traits<EdgeWeights>::reference b) const
  {
    if (a.get<0>() == 0)
      return make_tuple(b.get<0>(), a.get<1>() + b.get<1>(), a.get<2>() + b.get<2>());
    else
      return make_tuple(a.get<0>(), a.get<1>() + b.get<1>(), a.get<2>() + b.get<2>());
  }
};

template<>
struct property_traits<VertexIds> {
  // Metric property map
  typedef uint32_t value_type;
  typedef uint32_t reference;
  typedef ns3::Ptr<ns3::ndn::GlobalRouter> key_type;
  typedef readable_property_map_tag category;
};

inline EdgeWeights
get(edge_weight_t, const NdnGlobalRouterGraph& g)
{
  return EdgeWeights(g);
}

inline VertexIds
get(vertex_index_t, const NdnGlobalRouterGraph& g)
{
  return VertexIds(g);
}

template<class M, class K, class V>
inline void
put(reference_wrapper<M> mapp, K a, V p)
{
  mapp.get()[a] = p;
}

// void
// put (cref< std::map< ns3::Ptr<ns3::ndn::GlobalRouter>, ns3::Ptr<ns3::ndn::GlobalRouter> > > map,

inline uint32_t
get(const boost::VertexIds&, ns3::Ptr<ns3::ndn::GlobalRouter>& gr)
{
  return gr->GetId();
}

inline property_traits<EdgeWeights>::reference
get(const boost::EdgeWeights&, ns3::ndn::GlobalRouter::Incidency& edge)
{
  if (edge.get<1>() == 0)
    return property_traits<EdgeWeights>::reference(0, 0, 0.0);
  else {
    ns3::Ptr<ns3::ndn::Limits> limits = edge.get<1>()->GetObject<ns3::ndn::Limits>();
    double delay = 0.0;
    if (limits != 0) // valid limits object
    {
      delay = limits->GetLinkDelay();
    }
    return property_traits<EdgeWeights>::reference(edge.get<1>(), edge.get<1>()->GetMetric(),
                                                   delay);
  }
}

struct PredecessorsMap
  : public std::map<ns3::Ptr<ns3::ndn::GlobalRouter>, ns3::Ptr<ns3::ndn::GlobalRouter>> {
};

template<>
struct property_traits<reference_wrapper<PredecessorsMap>> {
  // Metric property map
  typedef ns3::Ptr<ns3::ndn::GlobalRouter> value_type;
  typedef ns3::Ptr<ns3::ndn::GlobalRouter> reference;
  typedef ns3::Ptr<ns3::ndn::GlobalRouter> key_type;
  typedef read_write_property_map_tag category;
};

struct DistancesMap : public std::map<ns3::Ptr<ns3::ndn::GlobalRouter>,
                                      tuple<ns3::Ptr<ns3::ndn::Face>, uint32_t, double>> {
};

template<>
struct property_traits<reference_wrapper<DistancesMap>> {
  // Metric property map
  typedef tuple<ns3::Ptr<ns3::ndn::Face>, uint32_t, double> value_type;
  typedef tuple<ns3::Ptr<ns3::ndn::Face>, uint32_t, double> reference;
  typedef ns3::Ptr<ns3::ndn::GlobalRouter> key_type;
  typedef read_write_property_map_tag category;
};

inline tuple<ns3::Ptr<ns3::ndn::Face>, uint32_t, double>
get(DistancesMap& map, ns3::Ptr<ns3::ndn::GlobalRouter> key)
{
  boost::DistancesMap::iterator i = map.find(key);
  if (i == map.end())
    return tuple<ns3::Ptr<ns3::ndn::Face>, uint32_t, double>(0,
                                                             std::numeric_limits<uint32_t>::max(),
                                                             0.0);
  else
    return i->second;
}

} // namespace boost

/// @endcond

#endif // BOOST_GRAPH_NDN_GLOBAL_ROUTING_HELPER_H
