/* -*- 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_NAME_TREE_ENTRY_HPP
#define NFD_DAEMON_TABLE_NAME_TREE_ENTRY_HPP

#include "table/fib-entry.hpp"
#include "table/pit-entry.hpp"
#include "table/measurements-entry.hpp"
#include "table/strategy-choice-entry.hpp"

namespace nfd::name_tree {

class Node;

/** \brief An entry in the name tree
 */
class Entry : noncopyable
{
public:
  Entry(const Name& prefix, Node* node);

  const Name&
  getName() const
  {
    return m_name;
  }

  /** \return entry of getName().getPrefix(-1)
   *  \retval nullptr this entry is the root entry, i.e. getName() == Name()
   */
  Entry*
  getParent() const
  {
    return m_parent;
  }

  /** \brief Set parent of this entry
   *  \param entry entry of getName().getPrefix(-1)
   *  \pre getParent() == nullptr
   *  \post getParent() == &entry
   *  \post entry.getChildren() contains this
   */
  void
  setParent(Entry& entry);

  /** \brief Unset parent of this entry
   *  \post getParent() == nullptr
   *  \post parent.getChildren() does not contain this
   */
  void
  unsetParent();

  /** \brief Check whether this entry has any children
   */
  bool
  hasChildren() const
  {
    return !m_children.empty();
  }

  /** \return children of this entry
   */
  const std::vector<Entry*>&
  getChildren() const
  {
    return m_children;
  }

  /** \retval true this entry has no children and no table entries
   *  \retval false this entry has child or attached table entry
   */
  bool
  isEmpty() const
  {
    return !this->hasChildren() && !this->hasTableEntries();
  }

public: // attached table entries
  /** \retval true at least one table entries is attached
   *  \retval false no table entry is attached
   */
  bool
  hasTableEntries() const;

  fib::Entry*
  getFibEntry() const
  {
    return m_fibEntry.get();
  }

  void
  setFibEntry(unique_ptr<fib::Entry> fibEntry);

  bool
  hasPitEntries() const
  {
    return !this->getPitEntries().empty();
  }

  const std::vector<shared_ptr<pit::Entry>>&
  getPitEntries() const
  {
    return m_pitEntries;
  }

  void
  insertPitEntry(shared_ptr<pit::Entry> pitEntry);

  void
  erasePitEntry(pit::Entry* pitEntry);

  measurements::Entry*
  getMeasurementsEntry() const
  {
    return m_measurementsEntry.get();
  }

  void
  setMeasurementsEntry(unique_ptr<measurements::Entry> measurementsEntry);

  strategy_choice::Entry*
  getStrategyChoiceEntry() const
  {
    return m_strategyChoiceEntry.get();
  }

  void
  setStrategyChoiceEntry(unique_ptr<strategy_choice::Entry> strategyChoiceEntry);

  /** \return name tree entry on which a table entry is attached,
   *          or nullptr if the table entry is detached
   *  \note This function is for NameTree internal use. Other components
   *        should use NameTree::getEntry(tableEntry) instead.
   */
  template<typename ENTRY>
  static Entry*
  get(const ENTRY& tableEntry)
  {
    return tableEntry.m_nameTreeEntry;
  }

private:
  Name m_name;
  Node* m_node;
  Entry* m_parent = nullptr;
  std::vector<Entry*> m_children;

  unique_ptr<fib::Entry> m_fibEntry;
  std::vector<shared_ptr<pit::Entry>> m_pitEntries;
  unique_ptr<measurements::Entry> m_measurementsEntry;
  unique_ptr<strategy_choice::Entry> m_strategyChoiceEntry;

  friend Node* getNode(const Entry& entry);
};

/** \brief a functor to get a table entry from a name tree entry
 *  \tparam ENTRY type of single table entry attached to name tree entry, such as fib::Entry
 */
template<typename ENTRY>
class GetTableEntry
{
public:
  /** \brief A function pointer to the getter on Entry class that returns ENTRY
   */
  using Getter = ENTRY* (Entry::*)() const;

  /** \note The default argument is needed to ensure FIB and StrategyChoice iterators
   *        are default-constructible.
   */
  explicit
  GetTableEntry(Getter getter = nullptr)
    : m_getter(getter)
  {
  }

  const ENTRY&
  operator()(const Entry& nte) const
  {
    return *(nte.*m_getter)();
  }

private:
  Getter m_getter;
};

} // namespace nfd::name_tree

#endif // NFD_DAEMON_TABLE_NAME_TREE_ENTRY_HPP
