/* -*-  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 NDNSIM_PER_FIB_LIMITS_H
#define NDNSIM_PER_FIB_LIMITS_H

#include "ns3/event-id.h"
#include "ns3/log.h"
#include "ns3/ndn-pit.h"
#include "ns3/ndn-pit-entry.h"
#include "ns3/simulator.h"
#include "ns3/string.h"

#include "ns3/ndn-forwarding-strategy.h"

#include "ns3/ndn-limits.h"

namespace ns3 {
namespace ndn {
namespace fw {

/**
 * \ingroup ndn
 * \brief Strategy implementing per-FIB entry limits
 */
template<class Parent>
class PerFibLimits :
    public Parent
{
private:
  typedef Parent super;

public:
  static TypeId
  GetTypeId ();

  /**
   * @brief Helper function to retrieve logging name for the forwarding strategy
   */
  static std::string
  GetLogName ();
  
  /**
   * @brief Default constructor
   */
  PerFibLimits ()
  { }
  
  /// \copydoc ForwardingStrategy::WillEraseTimedOutPendingInterest
  virtual void
  WillEraseTimedOutPendingInterest (Ptr<pit::Entry> pitEntry);

  /// \copydoc ForwardingStrategy::AddFace
  virtual void
  AddFace (Ptr<Face> face)
  {
    super::AddFace (face);

    if (face->GetObject<Limits> () == 0)
      {
        NS_FATAL_ERROR ("At least per-face limits should be enabled");
        exit (1);
      }
  }
  
protected:
  /// \copydoc ForwardingStrategy::CanSendOutInterest
  virtual bool
  CanSendOutInterest (Ptr<Face> inFace,
                      Ptr<Face> outFace,
                      Ptr<const InterestHeader> header,
                      Ptr<const Packet> origPacket,
                      Ptr<pit::Entry> pitEntry);
  
  /// \copydoc ForwardingStrategy::WillSatisfyPendingInterest
  virtual void
  WillSatisfyPendingInterest (Ptr<Face> inFace,
                              Ptr<pit::Entry> pitEntry);

protected:
  static LogComponent g_log; ///< @brief Logging variable
  
private:
  std::string m_limitType;
};

template<class Parent>
LogComponent PerFibLimits<Parent>::g_log = LogComponent (PerFibLimits<Parent>::GetLogName ().c_str ());

template<class Parent>
std::string
PerFibLimits<Parent>::GetLogName ()
{
  return super::GetLogName ()+".PerFibLimits";
}

template<class Parent>
TypeId
PerFibLimits<Parent>::GetTypeId (void)
{
  static TypeId tid = TypeId ((super::GetTypeId ().GetName ()+"::PerFibLimits").c_str ())
    .SetGroupName ("Ndn")
    .template SetParent <super> ()
    .template AddConstructor <PerFibLimits> ()
    ;
  return tid;
}

template<class Parent>
bool
PerFibLimits<Parent>::CanSendOutInterest (Ptr<Face> inFace,
                                          Ptr<Face> outFace,
                                          Ptr<const InterestHeader> header,
                                          Ptr<const Packet> origPacket,
                                          Ptr<pit::Entry> pitEntry)
{
  NS_LOG_FUNCTION (this << pitEntry->GetPrefix ());

  Ptr<Limits> fibLimits = pitEntry->GetFibEntry ()->template GetObject<Limits> ();
  // no checks for the limit here. the check should be somewhere elese
  
  if (fibLimits->IsBelowLimit ())
    {
      if (super::CanSendOutInterest (inFace, outFace, header, origPacket, pitEntry))
        {
          fibLimits->BorrowLimit ();
          return true;
        }
    }
  
  return false;
}

template<class Parent>
void
PerFibLimits<Parent>::WillEraseTimedOutPendingInterest (Ptr<pit::Entry> pitEntry)
{
  NS_LOG_FUNCTION (this << pitEntry->GetPrefix ());

  Ptr<Limits> fibLimits = pitEntry->GetFibEntry ()->template GetObject<Limits> ();
  fibLimits->ReturnLimit ();

  super::WillEraseTimedOutPendingInterest (pitEntry);
}


template<class Parent>
void
PerFibLimits<Parent>::WillSatisfyPendingInterest (Ptr<Face> inFace,
                                                        Ptr<pit::Entry> pitEntry)
{
  NS_LOG_FUNCTION (this << pitEntry->GetPrefix ());

  Ptr<Limits> fibLimits = pitEntry->GetFibEntry ()->template GetObject<Limits> ();
  fibLimits->ReturnLimit ();
  
  super::WillSatisfyPendingInterest (inFace, pitEntry);
}

} // namespace fw
} // namespace ndn
} // namespace ns3

#endif // NDNSIM_PER_FIB_LIMITS_H
