/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2014  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
 *
 * 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/>.
 *
 * \author Ilya Moiseenko <iliamo@ucla.edu>
 */

#ifndef NFD_TABLE_CS_ENTRY_HPP
#define NFD_TABLE_CS_ENTRY_HPP

#include "common.hpp"
#include <ndn-cpp-dev/util/crypto.hpp>

namespace nfd {

namespace cs {

class Entry;

/** \brief represents a CS entry
 */
class Entry : noncopyable
{
public:
  typedef std::map<int, std::list<Entry*>::iterator > LayerIterators;

  Entry();

  /** \brief releases reference counts on shared objects
   */
  void
  release();

  /** \brief returns the name of the Data packet stored in the CS entry
   *  \return{ NDN name }
   */
  const Name&
  getName() const;

  /** \brief Data packet is unsolicited if this particular NDN node
   *  did not receive an Interest packet for it, or the Interest packet has already expired
   *  \return{ True if the Data packet is unsolicited; otherwise False  }
   */
  bool
  isUnsolicited() const;

  /** \brief returns the absolute time when Data becomes expired
   *  \return{ Time (resolution up to time::milliseconds) }
   */
  const time::steady_clock::TimePoint&
  getStaleTime() const;

  /** \brief returns the Data packet stored in the CS entry
   */
  const Data&
  getData() const;

  /** \brief changes the content of CS entry and recomputes digest
   */
  void
  setData(const Data& data, bool isUnsolicited);

  /** \brief changes the content of CS entry and modifies digest
   */
  void
  setData(const Data& data, bool isUnsolicited, const ndn::ConstBufferPtr& digest);

  /** \brief refreshes the time when Data becomes expired
   *  according to the current absolute time.
   */
  void
  updateStaleTime();

  /** \brief returns the digest of the Data packet stored in the CS entry.
   */
  const ndn::ConstBufferPtr&
  getDigest() const;

  /** \brief saves the iterator pointing to the CS entry on a specific layer of skip list
   */
  void
  setIterator(int layer, const LayerIterators::mapped_type& layerIterator);

  /** \brief removes the iterator pointing to the CS entry on a specific layer of skip list
   */
  void
  removeIterator(int layer);

  /** \brief returns the table containing <layer, iterator> pairs.
   */
  const LayerIterators&
  getIterators() const;

private:
  /** \brief prints <layer, iterator> pairs.
   */
  void
  printIterators() const;

private:
  time::steady_clock::TimePoint m_staleAt;
  shared_ptr<const Data> m_dataPacket;

  bool m_isUnsolicited;
  Name m_nameWithDigest;

  mutable ndn::ConstBufferPtr m_digest;

  LayerIterators m_layerIterators;
};

inline
Entry::Entry()
{
}

inline const Name&
Entry::getName() const
{
  return m_nameWithDigest;
}

inline const Data&
Entry::getData() const
{
  return *m_dataPacket;
}

inline bool
Entry::isUnsolicited() const
{
  return m_isUnsolicited;
}

inline const time::steady_clock::TimePoint&
Entry::getStaleTime() const
{
  return m_staleAt;
}

inline const Entry::LayerIterators&
Entry::getIterators() const
{
  return m_layerIterators;
}

} // namespace cs
} // namespace nfd

#endif // NFD_TABLE_CS_ENTRY_HPP
