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

class NameTree;

namespace name_tree {
class Entry;
} // namespace name_tree

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;

  shared_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
