/* -*- 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-rit.h"

#include "ns3/log.h"
#include "ns3/simulator.h"
#include "ns3/ccnx-interest-header.h"
#include "ns3/assert.h"

#include <utility>

NS_LOG_COMPONENT_DEFINE ("CcnxRit");

namespace ns3 {

using namespace __ccnx_private_rit;

NS_OBJECT_ENSURE_REGISTERED (CcnxRit);

TypeId 
CcnxRit::GetTypeId (void)
{
  static TypeId tid = TypeId ("ns3::CcnxRit")
    .SetGroupName ("Ccnx")
    .SetParent<Object> ()
    .AddConstructor<CcnxRit> ()
    .AddAttribute ("RitTimeout",
                   "Timeout defining how long records should be kept in RIT",
                   TimeValue (Seconds (1)),
                   MakeTimeAccessor (&CcnxRit::GetRitTimeout, &CcnxRit::SetRitTimeout),
                   MakeTimeChecker ())
    .AddAttribute ("CleanupTimeout",
                   "Timeout defining how frequent RIT should be cleaned up",
                   TimeValue (Seconds (1)),
                   MakeTimeAccessor (&CcnxRit::GetCleanupTimeout, &CcnxRit::SetCleanupTimeout),
                   MakeTimeChecker ())
    ;

  return tid;
}


//////////////////////////////////////////////////////////////////////
// Helper classes
//////////////////////////////////////////////////////////////////////
/**
 * \ingroup ccnx
 * \brief Typedef for nonce hash index of RIT container
 */
struct CcnxRitByNonce
{
  typedef
  CcnxRitContainer::type::index<nonce>::type
  type;
};

// /**
//  * \ingroup ccnx
//  * \brief Typedef for prefix hash index of RIT container
//  */
// struct CcnxRitByTimestamp
// {
//   typedef
//   CcnxRitContainer::type::index<timestamp>::type
//   type;
// };

//////////////////////////////////////////////////////////////////////


CcnxRit::CcnxRit( )
{
}

CcnxRit::~CcnxRit( ) { }

void
CcnxRit::SetRitTimeout (const Time &timeout)
{
  m_ritTimeout = timeout;
}

Time
CcnxRit::GetRitTimeout () const
{
  return m_ritTimeout;
}

void
CcnxRit::SetCleanupTimeout (const Time &timeout)
{
  m_cleanupTimeout = timeout;
  if (m_cleanupEvent.IsRunning ())
    m_cleanupEvent.Cancel (); // cancel any scheduled cleanup events

  // schedule even with new timeout
  m_cleanupEvent = Simulator::Schedule (Simulator::Now () + m_cleanupTimeout,
                                        &CcnxRit::CleanExpired, this); 
}

Time
CcnxRit::GetCleanupTimeout () const
{
  return m_cleanupTimeout;
}

bool
CcnxRit::WasRecentlySatisfied (const CcnxInterestHeader &header)
{
  NS_LOG_FUNCTION_NOARGS ();
  std::pair<CcnxRitByNonce::type::iterator,CcnxRitByNonce::type::iterator>
    entries = get<nonce> ().equal_range (header.GetNonce ());
  
  if (entries.first == end ())
    return false;

  // check all entries if the name of RIT entry matches the name of interest
  for (CcnxRitByNonce::type::iterator it = entries.first; it != entries.second; it++)
    {
      // NS_LOG_DEBUG (it->m_prefix << " vs " << header.GetName () << " = " << (it->m_prefix == header.GetName ()));
      if (it->m_prefix == header.GetName ())
        return true;
    }

  return false;
}

void
CcnxRit::SetRecentlySatisfied (const CcnxInterestHeader &header)
{
  NS_LOG_FUNCTION_NOARGS ();
  NS_ASSERT_MSG (!WasRecentlySatisfied (header), "Duplicate recent interest should not be added to RIT");
  
  get<timestamp> ().push_back (
                               CcnxRitEntry(header.GetName (),
                                            header.GetNonce (),
                                            Simulator::Now ()+m_ritTimeout)
                               );
}


void CcnxRit::CleanExpired ()
{
  // NS_LOG_LOGIC ("Cleaning RIT");
  Time now = Simulator::Now ();
// #ifdef _DEBUG
//   uint32_t count = 0;
// #endif
  
  while( !empty() )
    {
      if( get<timestamp> ().front ().m_expireTime <= now ) // is the record stale?
        {
         get<timestamp> ().pop_front( );
// #ifdef _DEBUG
//          count++;
// #endif
        }
      else
        break; // nothing else to do. All later records will not be stale
    }
// #ifdef _DEBUG
//   NS_LOG_DEBUG (count << " records cleaned");
// #endif
  
  // schedule next even
  m_cleanupEvent = Simulator::Schedule (Simulator::Now () + m_cleanupTimeout,
                                        &CcnxRit::CleanExpired, this); 
}

} //namespace ns3
