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

#include "ns3/ndnSIM/model/ndn-common.hpp"

#include "content-store-impl.hpp"

#include "../../utils/trie/multi-policy.hpp"
#include "custom-policies/lifetime-stats-policy.hpp"

namespace ns3 {
namespace ndn {
namespace cs {

/**
 * @ingroup ndn-cs
 * @brief Special content store realization that provides ability to track stats of CS operations
 */
template<class Policy>
class ContentStoreWithStats
  : public ContentStoreImpl<ndnSIM::
                              multi_policy_traits<boost::mpl::
                                                    vector2<Policy,
                                                            ndnSIM::
                                                              lifetime_stats_policy_traits>>> {
public:
  typedef ContentStoreImpl<ndnSIM::
                             multi_policy_traits<boost::mpl::
                                                   vector2<Policy,
                                                           ndnSIM::lifetime_stats_policy_traits>>>
    super;

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

  ContentStoreWithStats()
  {
    // connect traceback to the policy
    super::getPolicy().template get<1>().set_traced_callback(&m_willRemoveEntry);
  }

  static TypeId
  GetTypeId();

  virtual inline void
  Print(std::ostream& os) const;

private:
  static LogComponent g_log; ///< @brief Logging variable

  /// @brief trace of for entry removal: first parameter is pointer to the CS entry, second is how
  /// long entry was in the cache
  TracedCallback<Ptr<const Entry>, Time> m_willRemoveEntry;
};

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

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

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

      .AddTraceSource("WillRemoveEntry",
                      "Trace called just before content store entry will be removed",
                      MakeTraceSourceAccessor(&ContentStoreWithStats<Policy>::m_willRemoveEntry))

    // trace stuff here
    ;

  return tid;
}

template<class Policy>
void
ContentStoreWithStats<Policy>::Print(std::ostream& os) const
{
  // const freshness_policy_container &freshness = this->getPolicy ().template
  // get<freshness_policy_container> ();

  for (typename super::policy_container::const_iterator item = this->getPolicy().begin();
       item != this->getPolicy().end(); item++) {
    Time alive = lifetime_stats_container::policy_base::get_time(&(*item)) - Simulator::Now();
    os << item->payload()->GetName() << "(alive: " << alive.ToDouble(Time::S) << "s)" << std::endl;
  }
}

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

#endif // NDN_CONTENT_STORE_IMPL_H_
