/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2014-2016,  Regents of the University of California,
 *                           Arizona Board of Regents,
 *                           Colorado State University,
 *                           University Pierre & Marie Curie, Sorbonne University,
 *                           Washington University in St. Louis,
 *                           Beijing Institute of Technology,
 *                           The University of Memphis.
 *
 * This file is part of NFD (Named Data Networking Forwarding Daemon).
 * See AUTHORS.md for complete list of NFD authors and contributors.
 *
 * NFD is free software: you can redistribute it and/or modify it under the terms
 * of the GNU General Public License as published by the Free Software Foundation,
 * either version 3 of the License, or (at your option) any later version.
 *
 * NFD 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
 * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef NFD_DAEMON_TABLE_PIT_ENTRY_HPP
#define NFD_DAEMON_TABLE_PIT_ENTRY_HPP

#include "pit-in-record.hpp"
#include "pit-out-record.hpp"
#include "core/scheduler.hpp"

namespace nfd {

namespace name_tree {
class NameTree;
class Entry;
} // namespace name_tree
using name_tree::NameTree;

namespace pit {

/** \brief an unordered collection of in-records
 */
typedef std::list<InRecord> InRecordCollection;

/** \brief an unordered collection of out-records
 */
typedef std::list<OutRecord> OutRecordCollection;

/** \brief an Interest table entry
 *
 *  An Interest table entry represents either a pending Interest or a recently satisfied Interest.
 *  Each entry contains a collection of in-records, a collection of out-records,
 *  and two timers used in forwarding pipelines.
 *  In addition, the entry, in-records, and out-records are subclasses of StrategyInfoHost,
 *  which allows forwarding strategy to store arbitrary information on them.
 */
class Entry : public StrategyInfoHost, noncopyable
{
public:
  explicit
  Entry(const Interest& interest);

  /** \return the representative Interest of the PIT entry
   *  \note Every Interest in in-records and out-records should have same Name and Selectors
   *        as the representative Interest.
   *  \todo #3162 require Link field to match the representative Interest
   */
  const Interest&
  getInterest() const;

  /** \return Interest Name
   */
  const Name&
  getName() const;

public: // in-record
  /** \return collection of in-records
   */
  const InRecordCollection&
  getInRecords() const;

  /** \retval true There is at least one in-record.
   *               This implies some downstream is waiting for Data or Nack.
   *  \retval false There is no in-record.
   *                This implies the entry is new or has been satisfied or Nacked.
   */
  bool
  hasInRecords() const;

  InRecordCollection::iterator
  in_begin();

  InRecordCollection::const_iterator
  in_begin() const;

  InRecordCollection::iterator
  in_end();

  InRecordCollection::const_iterator
  in_end() const;

  /** \brief get the in-record for \p face
   *  \return an iterator to the in-record, or .in_end() if it does not exist
   */
  InRecordCollection::iterator
  getInRecord(const Face& face);

  /** \brief insert or update an in-record
   *  \return an iterator to the new or updated in-record
   */
  InRecordCollection::iterator
  insertOrUpdateInRecord(shared_ptr<Face> face, const Interest& interest);

  /** \brief delete the in-record for \p face if it exists
   */
  void
  deleteInRecord(const Face& face);

  /** \brief delete all in-records
   */
  void
  clearInRecords();

public: // out-record
  /** \return collection of in-records
   */
  const OutRecordCollection&
  getOutRecords() const;

  /** \retval true There is at least one out-record.
   *               This implies the Interest has been forwarded to some upstream,
   *               and they haven't returned Data, but may have returned Nacks.
   *  \retval false There is no out-record.
   *                This implies the Interest has not been forwarded.
   */
  bool
  hasOutRecords() const;

  OutRecordCollection::iterator
  out_begin();

  OutRecordCollection::const_iterator
  out_begin() const;

  OutRecordCollection::iterator
  out_end();

  OutRecordCollection::const_iterator
  out_end() const;

  /** \brief get the out-record for \p face
   *  \return an iterator to the out-record, or .out_end() if it does not exist
   */
  OutRecordCollection::iterator
  getOutRecord(const Face& face);

  /** \brief insert or update an out-record
   *  \return an iterator to the new or updated out-record
   */
  OutRecordCollection::iterator
  insertOrUpdateOutRecord(shared_ptr<Face> face, const Interest& interest);

  /** \brief delete the out-record for \p face if it exists
   */
  void
  deleteOutRecord(const Face& face);

public:
  /** \brief unsatisfy timer
   *
   *  This timer is used in forwarding pipelines to delete the entry
   *  when it expires without being satisfied.
   *  It fires when the last InterestLifetime among in-records expires.
   *
   *  Either this or the straggler timer should be set at all times,
   *  except when this entry is being processed in a pipeline.
   */
  scheduler::EventId m_unsatisfyTimer;

  /** \brief straggler timer
   *
   *  This timer is used in forwarding pipelines to delete the entry when it has been satisfied
   *  and is no longer needed for measurement collection purpose.
   *
   *  Either this or the unsatisfy timer should be set at all times,
   *  except when this entry is being processed in a pipeline.
   */
  scheduler::EventId m_stragglerTimer;

private:
  shared_ptr<const Interest> m_interest;
  InRecordCollection m_inRecords;
  OutRecordCollection m_outRecords;

  weak_ptr<name_tree::Entry> m_nameTreeEntry;

  friend class nfd::NameTree;
  friend class nfd::name_tree::Entry;
};

inline const Interest&
Entry::getInterest() const
{
  return *m_interest;
}

inline const Name&
Entry::getName() const
{
  return m_interest->getName();
}

inline const InRecordCollection&
Entry::getInRecords() const
{
  return m_inRecords;
}

inline bool
Entry::hasInRecords() const
{
  return !m_inRecords.empty();
}

inline InRecordCollection::iterator
Entry::in_begin()
{
  return m_inRecords.begin();
}

inline InRecordCollection::const_iterator
Entry::in_begin() const
{
  return m_inRecords.begin();
}

inline InRecordCollection::iterator
Entry::in_end()
{
  return m_inRecords.end();
}

inline InRecordCollection::const_iterator
Entry::in_end() const
{
  return m_inRecords.end();
}

inline const OutRecordCollection&
Entry::getOutRecords() const
{
  return m_outRecords;
}

inline bool
Entry::hasOutRecords() const
{
  return !m_outRecords.empty();
}

inline OutRecordCollection::iterator
Entry::out_begin()
{
  return m_outRecords.begin();
}

inline OutRecordCollection::const_iterator
Entry::out_begin() const
{
  return m_outRecords.begin();
}

inline OutRecordCollection::iterator
Entry::out_end()
{
  return m_outRecords.end();
}

inline OutRecordCollection::const_iterator
Entry::out_end() const
{
  return m_outRecords.end();
}

} // namespace pit
} // namespace nfd

#endif // NFD_DAEMON_TABLE_PIT_ENTRY_HPP
