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

#include "content-store-impl.h"

#include "../../utils/trie/multi-policy.h"
#include "../../utils/trie/freshness-policy.h"

namespace ns3 {
namespace ndn {
namespace cs {

template<class Policy>
class ContentStoreWithFreshness :
    public ContentStoreImpl< ndnSIM::multi_policy_traits< boost::mpl::vector2< Policy, ndnSIM::freshness_policy_traits > > >
{
public:
  typedef ContentStoreImpl< ndnSIM::multi_policy_traits< boost::mpl::vector2< Policy, ndnSIM::freshness_policy_traits > > > super;

  typedef typename super::policy_container::template index<1>::type freshness_policy_container;

  static TypeId
  GetTypeId ();
  
  virtual inline bool
  Add (Ptr<const ContentObjectHeader> header, Ptr<const Packet> packet);

private:
  inline void
  CleanExpired ();

  inline void
  RescheduleCleaning ();
  
private:
  static LogComponent g_log; ///< @brief Logging variable

  EventId m_cleanEvent;
  Time m_scheduledCleaningTime;
};

//////////////////////////////////////////
////////// Implementation ////////////////
//////////////////////////////////////////


template<class Policy>
LogComponent
ContentStoreWithFreshness< Policy >::g_log = LogComponent (("ndn.cs.Freshness." + Policy::GetName ()).c_str ());


template<class Policy>
TypeId
ContentStoreWithFreshness< Policy >::GetTypeId ()
{
  static TypeId tid = TypeId (("ns3::ndn::cs::Freshness::"+Policy::GetName ()).c_str ())
    .SetGroupName ("Ndn")
    .SetParent<super> ()
    .template AddConstructor< ContentStoreWithFreshness< Policy > > ()

    // trace stuff here
    ;

  return tid;
}


template<class Policy>
inline bool
ContentStoreWithFreshness< Policy >::Add (Ptr<const ContentObjectHeader> header, Ptr<const Packet> packet)
{
  bool ok = super::Add (header, packet);
  if (!ok) return false;

  NS_LOG_DEBUG (header->GetName () << " added to cache");
  RescheduleCleaning ();
  return true;
}

template<class Policy>
inline void
ContentStoreWithFreshness< Policy >::RescheduleCleaning ()
{
  const freshness_policy_container &freshness = this->getPolicy ().template get<freshness_policy_container> ();

  if (freshness.size () > 0)
    {
      Time nextStateTime = freshness_policy_container::policy_base::get_freshness (&(*freshness.begin ()));

      if (m_scheduledCleaningTime.IsZero () || // if not yet scheduled
          m_scheduledCleaningTime > nextStateTime) // if new item expire sooner than already scheduled
        {
          if (m_cleanEvent.IsRunning ())
            {
              Simulator::Remove (m_cleanEvent); // just canceling would not clean up list of events
            }

          // NS_LOG_DEBUG ("Next event in: " << (nextStateTime - Now ()).ToDouble (Time::S) << "s");
          m_cleanEvent = Simulator::Schedule (nextStateTime - Now (), &ContentStoreWithFreshness< Policy >::CleanExpired, this);
          m_scheduledCleaningTime = nextStateTime;
        }
    }
  else
    {
      if (m_cleanEvent.IsRunning ())
        {
          Simulator::Remove (m_cleanEvent); // just canceling would not clean up list of events
        }
    }
}


template<class Policy>
inline void
ContentStoreWithFreshness< Policy >::CleanExpired ()
{
  freshness_policy_container &freshness = this->getPolicy ().template get<freshness_policy_container> ();

  // NS_LOG_LOGIC (">> Cleaning: Total number of items:" << this->getPolicy ().size () << ", items with freshness: " << freshness.size ());
  Time now = Simulator::Now ();

  while (!freshness.empty ())
    {
      typename freshness_policy_container::iterator entry = freshness.begin ();

      if (freshness_policy_container::policy_base::get_freshness (&(*entry)) <= now) // is the record stale?
        {
          super::erase (&(*entry));
        }
      else
        break; // nothing else to do. All later records will not be stale
    }
  // NS_LOG_LOGIC ("<< Cleaning: Total number of items:" << this->getPolicy ().size () << ", items with freshness: " << freshness.size ());

  m_scheduledCleaningTime = Time ();
  RescheduleCleaning ();
}


} // namespace cs
} // namespace ndn
} // namespace ns3

#endif // NDN_CONTENT_STORE_WITH_FRESHNESS_H_
