/* -*- 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 noexcept
  {
    return m_name;
  }

  /** \return entry of getName().getPrefix(-1)
   *  \retval nullptr this entry is the root entry, i.e. getName() == Name()
   */
  Entry*
  getParent() const noexcept
  {
    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();
  }

  /**
   * \brief Returns the children of this entry.
   */
  const std::vector<Entry*>&
  getChildren() const noexcept
  {
    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
