/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2014-2022,  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_CS_HPP
#define NFD_DAEMON_TABLE_CS_HPP

#include "cs-policy.hpp"

namespace nfd {
namespace cs {

/** \brief Implements the Content Store.
 *
 *  This Content Store implementation consists of a Table and a replacement policy.
 *
 *  The Table is a container ( \c std::set ) sorted by full Names of stored Data packets.
 *  Data packets are wrapped in Entry objects. Each Entry contains the Data packet itself,
 *  and a few additional attributes such as when the Data becomes non-fresh.
 *
 *  The replacement policy is implemented in a subclass of \c Policy.
 */
class Cs : noncopyable
{
public:
  explicit
  Cs(size_t nMaxPackets = 10);

  /** \brief Inserts a Data packet.
   */
  void
  insert(const Data& data, bool isUnsolicited = false);

  /** \brief Asynchronously erases entries under \p prefix.
   *  \tparam AfterEraseCallback `void f(size_t nErased)`
   *  \param prefix name prefix of entries
   *  \param limit max number of entries to erase
   *  \param cb callback to receive the actual number of erased entries; must not be empty;
   *            it may be invoked either before or after erase() returns
   */
  template<typename AfterEraseCallback>
  void
  erase(const Name& prefix, size_t limit, AfterEraseCallback&& cb)
  {
    size_t nErased = eraseImpl(prefix, limit);
    cb(nErased);
  }

  /** \brief Finds the best matching Data packet.
   *  \tparam HitCallback `void f(const Interest&, const Data&)`
   *  \tparam MissCallback `void f(const Interest&)`
   *  \param interest the Interest for lookup
   *  \param hit a callback if a match is found; must not be empty
   *  \param miss a callback if there's no match; must not be empty
   *  \note A lookup invokes either callback exactly once.
   *        The callback may be invoked either before or after find() returns
   */
  template<typename HitCallback, typename MissCallback>
  void
  find(const Interest& interest, HitCallback&& hit, MissCallback&& miss) const
  {
    auto match = findImpl(interest);
    if (match == m_table.end()) {
      miss(interest);
      return;
    }
    hit(interest, match->getData());
  }

  /** \brief Get number of stored packets.
   */
  size_t
  size() const
  {
    return m_table.size();
  }

public: // configuration
  /** \brief Get capacity (in number of packets).
   */
  size_t
  getLimit() const noexcept
  {
    return m_policy->getLimit();
  }

  /** \brief Change capacity (in number of packets).
   */
  void
  setLimit(size_t nMaxPackets)
  {
    return m_policy->setLimit(nMaxPackets);
  }

  /** \brief Get replacement policy.
   */
  Policy*
  getPolicy() const noexcept
  {
    return m_policy.get();
  }

  /** \brief Change replacement policy.
   *  \pre size() == 0
   */
  void
  setPolicy(unique_ptr<Policy> policy);

  /** \brief Get CS_ENABLE_ADMIT flag.
   *  \sa https://redmine.named-data.net/projects/nfd/wiki/CsMgmt#Update-config
   */
  bool
  shouldAdmit() const noexcept
  {
    return m_shouldAdmit;
  }

  /** \brief Set CS_ENABLE_ADMIT flag.
   *  \sa https://redmine.named-data.net/projects/nfd/wiki/CsMgmt#Update-config
   */
  void
  enableAdmit(bool shouldAdmit) noexcept;

  /** \brief Get CS_ENABLE_SERVE flag.
   *  \sa https://redmine.named-data.net/projects/nfd/wiki/CsMgmt#Update-config
   */
  bool
  shouldServe() const noexcept
  {
    return m_shouldServe;
  }

  /** \brief Set CS_ENABLE_SERVE flag.
   *  \sa https://redmine.named-data.net/projects/nfd/wiki/CsMgmt#Update-config
   */
  void
  enableServe(bool shouldServe) noexcept;

public: // enumeration
  using const_iterator = Table::const_iterator;

  const_iterator
  begin() const
  {
    return m_table.begin();
  }

  const_iterator
  end() const
  {
    return m_table.end();
  }

private:
  std::pair<const_iterator, const_iterator>
  findPrefixRange(const Name& prefix) const;

  size_t
  eraseImpl(const Name& prefix, size_t limit);

  const_iterator
  findImpl(const Interest& interest) const;

  void
  setPolicyImpl(unique_ptr<Policy> policy);

NFD_PUBLIC_WITH_TESTS_ELSE_PRIVATE:
  void
  dump();

private:
  Table m_table;
  unique_ptr<Policy> m_policy;
  signal::ScopedConnection m_beforeEvictConnection;

  bool m_shouldAdmit = true; ///< if false, no Data will be admitted
  bool m_shouldServe = true; ///< if false, all lookups will miss
};

} // namespace cs

using cs::Cs;

} // namespace nfd

#endif // NFD_DAEMON_TABLE_CS_HPP
