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

#include "ccnx-fib.h"

#include "ccnx.h"
#include "ccnx-face.h"
#include "ccnx-interest-header.h"

#include "ns3/node.h"
#include "ns3/assert.h"
#include "ns3/names.h"

#define NDN_RTO_ALPHA 0.125
#define NDN_RTO_BETA 0.25
#define NDN_RTO_K 4

//#define NDN_DEBUG_OSPF	0
//#define NDN_DEBUG_OSPF_NODES 0

//#define NDN_DUMP_FIB		0
namespace ns3 {


//////////////////////////////////////////////////////////////////////
// Helpers
//////////////////////////////////////////////////////////////////////
namespace __ccnx_private {

struct CcnxFibFaceMetricByFace
{
  typedef CcnxFibFaceMetricContainer::type::index<i_face>::type
  type;
};

struct ChangeStatus
{
  ChangeStatus (CcnxFibFaceMetric::Status status) : m_status (status) { }
  void operator() (CcnxFibFaceMetric &entry)
  {
    entry.m_status = m_status;
  }
private:
  CcnxFibFaceMetric::Status m_status;
};

struct ChangeMetric
{
  ChangeMetric (int32_t metric) : m_metric (metric) { }
  void operator() (CcnxFibFaceMetric &entry)
  {
    entry.m_routingCost = m_metric;
  }
private:
  int32_t m_metric;
};

// struct SearchByFace {
//   /**
//    * \brief To perform effective searches by CcnxFace
//    */
//   bool
//   operator() (const CcnxFibFaceMetric &m, const Ptr<CcnxFace> &face) const
//   {
//     return *(m.m_face) < *face;
//   } 

//   /**
//    * \brief To perform effective searches by CcnxFace
//    */
//   bool
//   operator() (const Ptr<CcnxFace> &face, const CcnxFibFaceMetric &m) const
//   {
//     return *face < *(m.m_face);
//   } 
// };

}
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////

using namespace __ccnx_private;

TypeId 
CcnxFib::GetTypeId (void)
{
  static TypeId tid = TypeId ("ns3::CcnxFib")
    .SetParent<Object> ()
    .SetGroupName ("Ccnx")
    .AddConstructor<CcnxFib> ()

  ;
  return tid;
}

void
CcnxFibFaceMetric::UpdateRtt::operator() (CcnxFibFaceMetric &entry)
{
  // const Time & this->m_rttSample
  
  //update srtt and rttvar (RFC 2988)
  if (entry.m_sRtt.IsZero ())
    {
      //first RTT measurement
      NS_ASSERT_MSG (entry.m_rttVar.IsZero (), "SRTT is zero, but variation is not");
      
      entry.m_sRtt = m_rttSample;
      entry.m_rttVar = Time (entry.m_sRtt / 2.0);
    }
  else
    {
      entry.m_rttVar = Time ((1 - NDN_RTO_BETA) * entry.m_rttVar + NDN_RTO_BETA * Abs(entry.m_sRtt - m_rttSample));
      entry.m_sRtt = Time ((1 - NDN_RTO_ALPHA) * entry.m_sRtt + NDN_RTO_ALPHA * m_rttSample);
    }
}

void
CcnxFibEntry::UpdateStatus::operator () (CcnxFibEntry &entry)
{
  CcnxFibFaceMetricByFace::type::iterator record = entry.m_faces.get<i_face> ().find (m_face);
  NS_ASSERT_MSG (record != entry.m_faces.get<i_face> ().end (),
                 "Update status can be performed only on existing faces of CcxnFibEntry");

  entry.m_faces.modify (record, ChangeStatus (m_status));

  // reordering random access index same way as by metric index
  entry.m_faces.get<i_nth> ().rearrange (entry.m_faces.get<i_metric> ().begin ());
}

void
CcnxFibEntry::AddOrUpdateRoutingMetric::operator () (CcnxFibEntry &entry)
{
  CcnxFibFaceMetricByFace::type::iterator record = entry.m_faces.get<i_face> ().find (m_face);
  if (record == entry.m_faces.get<i_face> ().end ())
    {
      entry.m_faces.insert (CcnxFibFaceMetric (m_face, m_metric));
    }
  else
    {
      entry.m_faces.modify (record, ChangeMetric (m_metric));
    }
  
  // reordering random access index same way as by metric index
  entry.m_faces.get<i_nth> ().rearrange (entry.m_faces.get<i_metric> ().begin ());
}

void
CcnxFibEntry::UpdateFaceRtt::operator() (CcnxFibEntry &entry)
{
  CcnxFibFaceMetricContainer::type::iterator metric = entry.m_faces.find (m_face);
  NS_ASSERT_MSG (metric != entry.m_faces.end (),
                 "Something wrong. Cannot find entry for the face in FIB");

  entry.m_faces.modify (metric, CcnxFibFaceMetric::UpdateRtt (m_rttSample));
}
    
Ptr<CcnxFace>
CcnxFibEntry::FindBestCandidate (int skip/* = 0*/) const
{
  skip = skip % m_faces.size();
  return m_faces.get<i_nth> () [skip].GetFace ();
}


CcnxFib::CcnxFib ()
{
}

void
CcnxFib::NotifyNewAggregate ()
{
  if (m_node == 0)
      m_node = this->GetObject<Node>();
  Object::NotifyNewAggregate ();
}

void 
CcnxFib::DoDispose (void)
{
  m_node = 0;
  Object::DoDispose ();
}


CcnxFibEntryContainer::type::iterator
CcnxFib::LongestPrefixMatch (const CcnxInterestHeader &interest) const
{
  const CcnxNameComponents &name = interest.GetName ();
  for (size_t componentsCount = name.GetComponents ().size ();
       componentsCount > 0;
       componentsCount--)
    {
      CcnxNameComponents subPrefix (name.GetSubComponents (componentsCount));
      CcnxFibEntryContainer::type::iterator match = find (subPrefix);
      if (match != end())
        return match;
    }
  
  return end ();
}


CcnxFibEntryContainer::type::iterator
CcnxFib::Add (const CcnxNameComponents &prefix, Ptr<CcnxFace> face, int32_t metric)
{
// CcnxFibFaceMetric
  CcnxFibEntryContainer::type::iterator entry = find (prefix);
  if (entry == end ())
    {
      entry = insert (end (), CcnxFibEntry (prefix));
      // insert new
    }
  modify (entry, CcnxFibEntry::AddOrUpdateRoutingMetric (face, metric));

  return entry;
}
    

std::ostream& operator<< (std::ostream& os, const CcnxFib &fib)
{
  os << "Node " << Names::FindName (fib.m_node) << "\n";
  os << "  Dest prefix      Interfaces(Costs)                  \n";
  os << "+-------------+--------------------------------------+\n";
  
  for (CcnxFibEntryContainer::type::iterator entry = fib.begin ();
       entry != fib.end ();
       entry++)
    {
      os << *entry << "\n";
    }
  return os;
}

std::ostream& operator<< (std::ostream& os, const CcnxFibEntry &entry)
{
  os << *entry.m_prefix << "\t";
  
  for (CcnxFibFaceMetricContainer::type::index<i_nth>::type::iterator metric =
         entry.m_faces.get<i_nth> ().begin ();
       metric != entry.m_faces.get<i_nth> ().end ();
       metric++)
    {
      if (metric != entry.m_faces.get<i_nth> ().begin ())
        os << ", ";

      os << *metric;
    }
  return os;
}

std::ostream& operator<< (std::ostream& os, const CcnxFibFaceMetric &metric)
{
  static const std::string statusString[] = {"","g","y","r"};

  os << *metric.m_face << "(" << metric.m_routingCost << ","<< statusString [metric.m_status] << ")";
  return os;
}

// void CcnxFib::resetProbing()
// {
//     for(FibRangeIterator fib = _fib.begin(); fib != _fib.end(); fib++)
//         VALUE(fib).needsProbing = true;
// }

// void CcnxFib::updateInterfaceStatus( int interface, int status )
// {
// 	for( FibRangeIterator fib = _fib.begin(); fib!=_fib.end(); fib++ )
// 	{
// 		VALUE(fib).updateStatus( interface, status );
// 	}
// }

} // namespace ns3
