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

#include "measurements.hpp"
#include "name-tree.hpp"
#include "pit-entry.hpp"
#include "fib-entry.hpp"
#include "daemon/global.hpp"

namespace nfd {
namespace measurements {

Measurements::Measurements(NameTree& nameTree)
  : m_nameTree(nameTree)
{
}

Entry&
Measurements::get(name_tree::Entry& nte)
{
  Entry* entry = nte.getMeasurementsEntry();
  if (entry != nullptr) {
    return *entry;
  }

  nte.setMeasurementsEntry(make_unique<Entry>(nte.getName()));
  ++m_nItems;
  entry = nte.getMeasurementsEntry();

  entry->m_expiry = time::steady_clock::now() + getInitialLifetime();
  entry->m_cleanup = getScheduler().schedule(getInitialLifetime(), [=] { cleanup(*entry); });

  return *entry;
}

Entry&
Measurements::get(const Name& name)
{
  name_tree::Entry& nte = m_nameTree.lookup(name, std::min(name.size(), getMaxDepth()));
  return this->get(nte);
}

Entry&
Measurements::get(const fib::Entry& fibEntry)
{
  name_tree::Entry& nte = m_nameTree.lookup(fibEntry);
  return this->get(nte);
}

Entry&
Measurements::get(const pit::Entry& pitEntry)
{
  name_tree::Entry& nte = m_nameTree.lookup(pitEntry);
  return this->get(nte);
}

Entry*
Measurements::getParent(const Entry& child)
{
  if (child.getName().empty()) { // the root entry
    return nullptr;
  }

  name_tree::Entry* nteChild = m_nameTree.getEntry(child);
  name_tree::Entry* nte = nteChild->getParent();
  BOOST_ASSERT(nte != nullptr);
  return &this->get(*nte);
}

template<typename K>
Entry*
Measurements::findLongestPrefixMatchImpl(const K& key, const EntryPredicate& pred) const
{
  name_tree::Entry* match = m_nameTree.findLongestPrefixMatch(key,
    [&pred] (const name_tree::Entry& nte) {
      const Entry* entry = nte.getMeasurementsEntry();
      return entry != nullptr && pred(*entry);
    });
  if (match != nullptr) {
    return match->getMeasurementsEntry();
  }
  return nullptr;
}

Entry*
Measurements::findLongestPrefixMatch(const Name& name, const EntryPredicate& pred) const
{
  return this->findLongestPrefixMatchImpl(name.getPrefix(NameTree::getMaxDepth()), pred);
}

Entry*
Measurements::findLongestPrefixMatch(const pit::Entry& pitEntry, const EntryPredicate& pred) const
{
  return this->findLongestPrefixMatch(pitEntry.getName(), pred);
}

Entry*
Measurements::findExactMatch(const Name& name) const
{
  const name_tree::Entry* nte = m_nameTree.findExactMatch(name);
  return nte == nullptr ? nullptr : nte->getMeasurementsEntry();
}

void
Measurements::extendLifetime(Entry& entry, const time::nanoseconds& lifetime)
{
  BOOST_ASSERT(m_nameTree.getEntry(entry) != nullptr);

  auto expiry = time::steady_clock::now() + lifetime;
  if (entry.m_expiry >= expiry) {
    // has longer lifetime, not extending
    return;
  }

  entry.m_cleanup.cancel();
  entry.m_expiry = expiry;
  entry.m_cleanup = getScheduler().schedule(lifetime, [&] { cleanup(entry); });
}

void
Measurements::cleanup(Entry& entry)
{
  name_tree::Entry* nte = m_nameTree.getEntry(entry);
  BOOST_ASSERT(nte != nullptr);

  nte->setMeasurementsEntry(nullptr);
  m_nameTree.eraseIfEmpty(nte);
  --m_nItems;
}

} // namespace measurements
} // namespace nfd
