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

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

namespace nfd {
namespace name_tree {

/** \brief an entry in the name tree
 */
class Entry : public enable_shared_from_this<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();

  /** \retval true this entry has at least one child
   *  \retval false this entry has no children
   */
  bool
  hasChildren() const
  {
    return !this->getChildren().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(shared_ptr<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);

private:
  Name m_name;
  Node* m_node;
  Entry* m_parent;
  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);
};

} // namespace name_tree
} // namespace nfd

#endif // NFD_DAEMON_TABLE_NAME_TREE_ENTRY_HPP
