/* -*- 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>
 */

#ifndef _NDN_PIT_ENTRY_H_
#define _NDN_PIT_ENTRY_H_

#include "ns3/ptr.h"
#include "ns3/simple-ref-count.h"

#include "ns3/ndn-fib.h"

#include "ns3/ndn-pit-entry-incoming-face.h"
#include "ns3/ndn-pit-entry-outgoing-face.h"

#include <boost/multi_index_container.hpp>
#include <boost/multi_index/tag.hpp>
#include <boost/multi_index/ordered_index.hpp>
// #include <boost/multi_index/composite_key.hpp>
// #include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/member.hpp>
// #include <boost/multi_index/mem_fun.hpp>
#include <set>
#include <boost/shared_ptr.hpp>

namespace ns3 {
namespace ndn {

class Pit;

namespace fw { class Tag; }

namespace pit {

/// @cond include_hidden
class i_face {};
class i_retx {};
/// @endcond

/**
 * \ingroup ndn
 * \brief Typedef for indexed face container of PitEntryOutgoingFace
 *
 * Indexes:
 * - by face (may be it will be possible to replace with just the std::map)
 */
// struct OutgoingFaceContainer
// {
//   /// @cond include_hidden
//   typedef boost::multi_index::multi_index_container<
//     OutgoingFace,
//     boost::multi_index::indexed_by<
//       // For fast access to elements using NdnFace
//       boost::multi_index::ordered_unique<
//         boost::multi_index::tag<i_face>,
//         boost::multi_index::member<OutgoingFace, Ptr<Face>, &OutgoingFace::m_face>
//       >
//       // ,
//       // boost::multi_index::ordered_non_unique<
//       //   boost::multi_index::tag<i_retx>,
//       //   boost::multi_index::member<OutgoingFace, uint32_t, &OutgoingFace::m_retxCount>
//       // >    
//     >
//    > type;
//   /// @endcond
// };


/**
 * \ingroup ndn
 * \brief structure for PIT entry
 *
 * All set-methods are virtual, in case index rearrangement is necessary in the derived classes
 */
class Entry : public SimpleRefCount<Entry>
{
public:
  typedef std::set< IncomingFace > in_container; ///< @brief incoming faces container type
  typedef in_container::iterator in_iterator;                ///< @brief iterator to incoming faces

  // typedef OutgoingFaceContainer::type out_container; ///< @brief outgoing faces container type
  typedef std::set< OutgoingFace > out_container; ///< @brief outgoing faces container type
  typedef out_container::iterator out_iterator;              ///< @brief iterator to outgoing faces

  typedef std::set< uint32_t > nonce_container;  ///< @brief nonce container type
  
  /**
   * \brief PIT entry constructor
   * \param prefix Prefix of the PIT entry
   * \param offsetTime Relative time to the current moment, representing PIT entry lifetime
   * \param fibEntry A FIB entry associated with the PIT entry
   */
  Entry (Pit &container, Ptr<const InterestHeader> header, Ptr<fib::Entry> fibEntry);

  /**
   * @brief Virtual destructor
   */
  virtual ~Entry ();
  
  /**
   * @brief Update lifetime of PIT entry
   *
   * This function will update PIT entry lifetime to the maximum of the current lifetime and
   * the lifetime Simulator::Now () + offsetTime
   *
   * @param lifetime Relative time to the current moment, representing PIT entry lifetime
   */
  virtual void
  UpdateLifetime (const Time &lifetime);

  /**
   * @brief Offset the currently set PIT lifetime (allowed both negative and positive offsets)
   * @param offsetTime positive or negative offset for the PIT lifetime.
   *
   * If PIT expire time becomes less than Simulator::Now, then it is adjusted to Simulator::Now.
   */
  virtual void
  OffsetLifetime (const Time &offsetTime);
  
  /**
   * @brief Get prefix of the PIT entry
   */
  const NameComponents &
  GetPrefix () const;
  
  /**
   * @brief Get current expiration time of the record
   *
   * @returns current expiration time of the record
   */
  const Time &
  GetExpireTime () const;
  
  /**
   * @brief Check if nonce `nonce` for the same prefix has already been seen
   *
   * @param nonce Nonce to check
   */
  bool
  IsNonceSeen (uint32_t nonce) const;
  
  /**
   * @brief Add `nonce` to the list of seen nonces
   *
   * @param nonce nonce to add to the list of seen nonces
   *
   * All nonces are stored for the lifetime of the PIT entry
   */
  virtual void
  AddSeenNonce (uint32_t nonce);
  
  /**
   * @brief Add `face` to the list of incoming faces
   *
   * @param face Face to add to the list of incoming faces
   * @returns iterator to the added entry
   */
  virtual in_iterator
  AddIncoming (Ptr<Face> face);

  /**
   * @brief Remove incoming entry for face `face`
   */
  virtual void
  RemoveIncoming (Ptr<Face> face);

  /**
   * @brief Clear all incoming faces either after all of them were satisfied or NACKed
   */
  virtual void
  ClearIncoming ();

  /**
   * @brief Add `face` to the list of outgoing faces
   *
   * @param face Face to add to the list of outgoing faces
   * @returns iterator to the added entry
   */
  virtual out_iterator
  AddOutgoing (Ptr<Face> face);

  /**
   * @brief Clear all incoming faces either after all of them were satisfied or NACKed
   */
  virtual void
  ClearOutgoing ();
  
  /**
   * @brief Remove all references to face.
   * 
   * This method should be called before face is completely removed from the stack.
   * Face is removed from the lists of incoming and outgoing faces
   */
  virtual void
  RemoveAllReferencesToFace (Ptr<Face> face);

  /**
   * @brief Flag outgoing face as hopeless
   */
  // virtual void
  // SetWaitingInVain (out_iterator face);
  virtual void
  SetWaitingInVain (Ptr<Face> face);
  
  /**
   * @brief Check if all outgoing faces are NACKed
   */
  bool
  AreAllOutgoingInVain () const;

  /**
   * @brief Similar to AreAllOutgoingInVain, but ignores `face`
   * \see AreAllOutgoingInVain
   **/
  bool
  AreTherePromisingOutgoingFacesExcept (Ptr<Face> face) const;

  /**
   * @brief Increase maximum limit of allowed retransmission per outgoing face
   */
  virtual void
  IncreaseAllowedRetxCount ();

  /**
   * @brief Get maximum allowed number of retransmissions via outgoing faces
   */
  uint32_t
  GetMaxRetxCount () const;

  /**
   * @brief Get associated FIB entry
   */
  Ptr<fib::Entry>
  GetFibEntry ();

  /**
   * @brief Get associated list (const reference) of incoming faces
   */
  const in_container &
  GetIncoming () const;

  /**
   * @brief Get associated list (const reference) of outgoing faces
   */
  const out_container &
  GetOutgoing () const;

  /**
   * @brief Get number of outgoing faces (needed for python bindings)
   */
  uint32_t
  GetOutgoingCount () const;
  
  /**
   * @brief Add new forwarding strategy tag
   */
  inline void
  AddFwTag (boost::shared_ptr< fw::Tag > tag);

  /**
   * @brief Get forwarding strategy tag (tag is not removed)
   */
  template<class T>
  inline boost::shared_ptr< T >
  GetFwTag ();

  /**
   * @brief Remove the forwarding strategy tag
   */
  template<class T>
  inline void
  RemoveFwTag ();

  /**
   * @brief Get InterestHeader (if several interests are received, then nonce is from the first Interest)
   */
  Ptr<const InterestHeader>
  GetInterest () const;

private:
  friend std::ostream& operator<< (std::ostream& os, const Entry &entry);
  
protected:
  Pit &m_container; ///< @brief Reference to the container (to rearrange indexes, if necessary)

  Ptr<const InterestHeader> m_interest; ///< \brief Interest of the PIT entry (if several interests are received, then nonce is from the first Interest)
  Ptr<fib::Entry> m_fibEntry;     ///< \brief FIB entry related to this prefix
  
  nonce_container m_seenNonces;  ///< \brief map of nonces that were seen for this prefix  
  in_container  m_incoming;      ///< \brief container for incoming interests
  out_container m_outgoing;      ///< \brief container for outgoing interests

  Time m_expireTime;         ///< \brief Time when PIT entry will be removed

  Time m_lastRetransmission; ///< @brief Last time when number of retransmissions were increased
  uint32_t m_maxRetxCount;   ///< @brief Maximum allowed number of retransmissions via outgoing faces

  std::list< boost::shared_ptr<fw::Tag> > m_fwTags; ///< @brief Forwarding strategy tags
};

std::ostream& operator<< (std::ostream& os, const Entry &entry);

inline void
Entry::AddFwTag (boost::shared_ptr< fw::Tag > tag)
{
  m_fwTags.push_back (tag);
}

/**
 * @brief Get and remove forwarding strategy tag
 */
template<class T>
inline boost::shared_ptr< T >
Entry::GetFwTag ()
{
  for (std::list< boost::shared_ptr<fw::Tag> >::iterator item = m_fwTags.begin ();
       item != m_fwTags.end ();
       item ++)
    {
      boost::shared_ptr< T > retPtr = boost::dynamic_pointer_cast<T> (*item);
      if (retPtr != boost::shared_ptr< T > ())
        {
          return retPtr;
        }
    }

  return boost::shared_ptr< T > ();
}

// /**
//  * @brief Peek the forwarding strategy tag
//  */
// template<class T>
// inline boost::shared_ptr< const T >
// Entry::PeekFwTag () const
// {
//   for (std::list< boost::shared_ptr<fw::Tag> >::const_iterator item = m_fwTags.begin ();
//        item != m_fwTags.end ();
//        item ++)
//     {
//       boost::shared_ptr< const T > retPtr = boost::dynamic_pointer_cast<const T> (*item);
//       if (retPtr != 0)
//         {
//           return retPtr;
//         }
//     }

//   return 0;
// }

template<class T>
inline void
Entry::RemoveFwTag ()
{
  for (std::list< boost::shared_ptr<fw::Tag> >::iterator item = m_fwTags.begin ();
       item != m_fwTags.end ();
       item ++)
    {
      boost::shared_ptr< T > retPtr = boost::dynamic_pointer_cast< T > (*item);
      if (retPtr != boost::shared_ptr< T > ())
        {
          m_fwTags.erase (item);
          return;
        }
    }
}


} // namespace pit
} // namespace ndn
} // namespace ns3

#endif // _NDN_PIT_ENTRY_H_
