/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2014,  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 "strategy-choice.hpp"
#include "core/logger.hpp"
#include "fw/strategy.hpp"
#include "pit-entry.hpp"
#include "measurements-entry.hpp"

namespace nfd {

using strategy_choice::Entry;
using fw::Strategy;

NFD_LOG_INIT("StrategyChoice");

StrategyChoice::StrategyChoice(NameTree& nameTree, shared_ptr<Strategy> defaultStrategy)
  : m_nameTree(nameTree)
  , m_nItems(0)
{
  this->setDefaultStrategy(defaultStrategy);
}

bool
StrategyChoice::hasStrategy(const Name& strategyName) const
{
  return m_strategyInstances.count(strategyName) > 0;
}

bool
StrategyChoice::install(shared_ptr<Strategy> strategy)
{
  BOOST_ASSERT(static_cast<bool>(strategy));
  const Name& strategyName = strategy->getName();

  if (this->hasStrategy(strategyName)) {
    NFD_LOG_ERROR("install(" << strategyName << ") duplicate strategyName");
    return false;
  }

  m_strategyInstances[strategyName] = strategy;
  return true;
}

bool
StrategyChoice::insert(const Name& prefix, const Name& strategyName)
{
  shared_ptr<name_tree::Entry> nameTreeEntry = m_nameTree.lookup(prefix);
  shared_ptr<Entry> entry = nameTreeEntry->getStrategyChoiceEntry();
  shared_ptr<Strategy> oldStrategy;

  if (static_cast<bool>(entry)) {
    if (entry->getStrategy().getName() == strategyName) {
      NFD_LOG_TRACE("insert(" << prefix << "," << strategyName << ") not changing");
      return true;
    }
    oldStrategy = entry->getStrategy().shared_from_this();
    NFD_LOG_TRACE("insert(" << prefix << "," << strategyName << ") "
                  "changing from " << oldStrategy->getName());
  }

  shared_ptr<Strategy> strategy = this->getStrategy(strategyName);
  if (!static_cast<bool>(strategy)) {
    NFD_LOG_ERROR("insert(" << prefix << "," << strategyName << ") strategy not installed");
    return false;
  }

  if (!static_cast<bool>(entry)) {
    oldStrategy = this->findEffectiveStrategy(prefix).shared_from_this();
    entry = make_shared<Entry>(prefix);
    nameTreeEntry->setStrategyChoiceEntry(entry);
    ++m_nItems;
    NFD_LOG_TRACE("insert(" << prefix << "," << strategyName << ") new entry");
  }

  this->changeStrategy(entry, oldStrategy, strategy);
  return true;
}

void
StrategyChoice::erase(const Name& prefix)
{
  BOOST_ASSERT(prefix.size() > 0);

  shared_ptr<name_tree::Entry> nameTreeEntry = m_nameTree.findExactMatch(prefix);
  if (!static_cast<bool>(nameTreeEntry)) {
    return;
  }

  shared_ptr<Entry> entry = nameTreeEntry->getStrategyChoiceEntry();
  if (!static_cast<bool>(entry)) {
    return;
  }

  Strategy& oldStrategy = entry->getStrategy();

  Strategy& parentStrategy = this->findEffectiveStrategy(prefix.getPrefix(-1));
  this->changeStrategy(entry, oldStrategy.shared_from_this(), parentStrategy.shared_from_this());

  nameTreeEntry->setStrategyChoiceEntry(shared_ptr<Entry>());
  --m_nItems;
}

shared_ptr<const Name>
StrategyChoice::get(const Name& prefix) const
{
  shared_ptr<name_tree::Entry> nameTreeEntry = m_nameTree.findExactMatch(prefix);
  if (!static_cast<bool>(nameTreeEntry)) {
    return shared_ptr<const Name>();
  }

  shared_ptr<Entry> entry = nameTreeEntry->getStrategyChoiceEntry();
  if (!static_cast<bool>(entry)) {
    return shared_ptr<const Name>();
  }

  return entry->getStrategy().getName().shared_from_this();
}

static inline bool
predicate_NameTreeEntry_hasStrategyChoiceEntry(const name_tree::Entry& entry)
{
  return static_cast<bool>(entry.getStrategyChoiceEntry());
}

Strategy&
StrategyChoice::findEffectiveStrategy(const Name& prefix) const
{
  shared_ptr<name_tree::Entry> nameTreeEntry =
    m_nameTree.findLongestPrefixMatch(prefix, &predicate_NameTreeEntry_hasStrategyChoiceEntry);
  BOOST_ASSERT(static_cast<bool>(nameTreeEntry));
  return nameTreeEntry->getStrategyChoiceEntry()->getStrategy();
}

Strategy&
StrategyChoice::findEffectiveStrategy(shared_ptr<name_tree::Entry> nameTreeEntry) const
{
  shared_ptr<strategy_choice::Entry> entry = nameTreeEntry->getStrategyChoiceEntry();
  if (static_cast<bool>(entry))
    return entry->getStrategy();
  nameTreeEntry = m_nameTree.findLongestPrefixMatch(nameTreeEntry,
                               &predicate_NameTreeEntry_hasStrategyChoiceEntry);
  BOOST_ASSERT(static_cast<bool>(nameTreeEntry));
  return nameTreeEntry->getStrategyChoiceEntry()->getStrategy();
}

Strategy&
StrategyChoice::findEffectiveStrategy(const pit::Entry& pitEntry) const
{
  shared_ptr<name_tree::Entry> nameTreeEntry = m_nameTree.get(pitEntry);

  BOOST_ASSERT(static_cast<bool>(nameTreeEntry));

  return findEffectiveStrategy(nameTreeEntry);
}

Strategy&
StrategyChoice::findEffectiveStrategy(const measurements::Entry& measurementsEntry) const
{
  shared_ptr<name_tree::Entry> nameTreeEntry = m_nameTree.get(measurementsEntry);

  BOOST_ASSERT(static_cast<bool>(nameTreeEntry));

  return findEffectiveStrategy(nameTreeEntry);
}

shared_ptr<fw::Strategy>
StrategyChoice::getStrategy(const Name& strategyName)
{
  StrategyInstanceTable::iterator it = m_strategyInstances.find(strategyName);
  return it != m_strategyInstances.end() ? it->second : shared_ptr<fw::Strategy>();
}

void
StrategyChoice::setDefaultStrategy(shared_ptr<Strategy> strategy)
{
  this->install(strategy);

  // don't use .insert here, because it will invoke findEffectiveStrategy
  // which expects an existing root entry
  shared_ptr<name_tree::Entry> nameTreeEntry = m_nameTree.lookup(Name());
  shared_ptr<Entry> entry = make_shared<Entry>(Name());
  nameTreeEntry->setStrategyChoiceEntry(entry);
  ++m_nItems;
  NFD_LOG_INFO("Set default strategy " << strategy->getName());

  entry->setStrategy(strategy);
}

/** \brief a predicate that decides whether StrategyInfo should be reset
 *
 *  StrategyInfo on a NameTree entry needs to be reset,
 *  if its effective strategy is covered by the changing StrategyChoice entry.
 */
static inline std::pair<bool,bool>
predicate_nameTreeEntry_needResetStrategyChoice(const name_tree::Entry& nameTreeEntry,
                                            const name_tree::Entry& rootEntry)
{
  if (&nameTreeEntry == &rootEntry) {
    return std::make_pair(true, true);
  }
  if (static_cast<bool>(nameTreeEntry.getStrategyChoiceEntry())) {
    return std::make_pair(false, false);
  }
  return std::make_pair(true, true);
}

static inline void
clearStrategyInfo_pitFaceRecord(const pit::FaceRecord& pitFaceRecord)
{
  const_cast<pit::FaceRecord&>(pitFaceRecord).clearStrategyInfo();
}

static inline void
clearStrategyInfo_pitEntry(shared_ptr<pit::Entry> pitEntry)
{
  pitEntry->clearStrategyInfo();
  std::for_each(pitEntry->getInRecords().begin(), pitEntry->getInRecords().end(),
                &clearStrategyInfo_pitFaceRecord);
  std::for_each(pitEntry->getOutRecords().begin(), pitEntry->getOutRecords().end(),
                &clearStrategyInfo_pitFaceRecord);
}

static inline void
clearStrategyInfo(const name_tree::Entry& nameTreeEntry)
{
  NFD_LOG_TRACE("clearStrategyInfo " << nameTreeEntry.getPrefix());

  std::for_each(nameTreeEntry.getPitEntries().begin(), nameTreeEntry.getPitEntries().end(),
                &clearStrategyInfo_pitEntry);
  if (static_cast<bool>(nameTreeEntry.getMeasurementsEntry())) {
    nameTreeEntry.getMeasurementsEntry()->clearStrategyInfo();
  }
}

void
StrategyChoice::changeStrategy(shared_ptr<strategy_choice::Entry> entry,
                               shared_ptr<fw::Strategy> oldStrategy,
                               shared_ptr<fw::Strategy> newStrategy)
{
  entry->setStrategy(newStrategy);
  if (oldStrategy == newStrategy) {
    return;
  }

  std::for_each(m_nameTree.partialEnumerate(entry->getPrefix(),
                           bind(&predicate_nameTreeEntry_needResetStrategyChoice,
                                _1, cref(*m_nameTree.get(*entry)))),
                m_nameTree.end(),
                &clearStrategyInfo);
}

StrategyChoice::const_iterator
StrategyChoice::begin() const
{
  return const_iterator(m_nameTree.fullEnumerate(&predicate_NameTreeEntry_hasStrategyChoiceEntry));
}

} // namespace nfd
