/* -*- 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/>.
 */

/** \file
 *  \brief allows testing forwarding in a network topology
 */

#ifndef NFD_TESTS_DAEMON_FW_TOPOLOGY_TESTER_HPP
#define NFD_TESTS_DAEMON_FW_TOPOLOGY_TESTER_HPP

#include "face/internal-transport.hpp"
#include "face/face.hpp"
#include "fw/strategy.hpp"
#include "choose-strategy.hpp"
#include "tests/test-common.hpp"

#include <ndn-cxx/face.hpp>

namespace nfd {
namespace fw {
namespace tests {

using namespace nfd::tests;

/** \brief identifies a node (forwarder) in the topology
 */
typedef size_t TopologyNode;

/** \brief represents a network link in the topology which connects two or more nodes
 */
class TopologyLink : noncopyable
{
public:
  explicit
  TopologyLink(const time::nanoseconds& delay);

  /** \brief fail the link, cause packets to be dropped silently
   */
  void
  fail()
  {
    m_isUp = false;
  }

  /** \brief recover the link from a failure
   */
  void
  recover()
  {
    m_isUp = true;
  }

  /** \brief change the link delay
   *  \param delay link delay, must be positive
   */
  void
  setDelay(const time::nanoseconds& delay);

  /** \brief attach a face to the link
   *  \param i forwarder index
   *  \param face a Face with InternalForwarderTransport
   */
  void
  addFace(TopologyNode i, shared_ptr<Face> face);

  /** \return a face of forwarder \p i which is attached to this link
   */
  Face&
  getFace(TopologyNode i)
  {
    return *m_faces.at(i);
  }

protected:
  /** \brief attach a Transport onto this link
   */
  void
  attachTransport(TopologyNode i, face::InternalTransportBase* transport);

private:
  void
  transmit(TopologyNode i, const Block& packet);

  void
  scheduleReceive(face::InternalTransportBase* recipient, const Block& packet);

private:
  bool m_isUp;
  time::nanoseconds m_delay;
  std::unordered_map<TopologyNode, face::InternalTransportBase*> m_transports;
  std::unordered_map<TopologyNode, shared_ptr<Face>> m_faces;
};

/** \brief represents a link to a local application
 */
class TopologyAppLink : noncopyable
{
public:
  /** \brief constructor
   *  \param forwarderFace a Face with InternalForwarderTransport
   */
  explicit
  TopologyAppLink(shared_ptr<Face> forwarderFace);

  /** \brief fail the link, cause packets to be dropped silently
   */
  void
  fail();

  /** \brief recover the link from a failure
   */
  void
  recover();

  /** \return face on forwarder side
   */
  Face&
  getForwarderFace()
  {
    return *m_face;
  }

  /** \return face on application side
   */
  ndn::Face&
  getClientFace()
  {
    return *m_client;
  }

private:
  shared_ptr<Face> m_face;
  face::InternalForwarderTransport* m_forwarderTransport;
  shared_ptr<face::InternalClientTransport> m_clientTransport;
  shared_ptr<ndn::Face> m_client;
};

/** \brief builds a topology for forwarding tests
 */
class TopologyTester : noncopyable
{
public:
  /** \brief creates a forwarder
   *  \return index of new forwarder
   */
  TopologyNode
  addForwarder(const std::string& label);

  /** \return forwarder instance \p i
   */
  Forwarder&
  getForwarder(TopologyNode i)
  {
    return *m_forwarders.at(i);
  }

  /** \brief sets strategy on forwarder \p i
   *  \tparam S the strategy type
   *  \note Test scenario can also access StrategyChoice table directly.
   */
  template<typename S>
  void
  setStrategy(TopologyNode i, Name prefix = Name("ndn:/"))
  {
    Forwarder& forwarder = this->getForwarder(i);
    choose<S>(forwarder, prefix);
  }

  /** \brief makes a link that interconnects two or more forwarders
   *
   *  A face is created on each of \p forwarders .
   *  When a packet is sent onto one of the faces on this link,
   *  this packet will be received by all other faces on this link after \p delay .
   */
  shared_ptr<TopologyLink>
  addLink(const std::string& label, const time::nanoseconds& delay,
          std::initializer_list<TopologyNode> forwarders,
          bool forceMultiAccessFace = false);

  /** \brief makes a link to local application
   */
  shared_ptr<TopologyAppLink>
  addAppFace(const std::string& label, TopologyNode i);

  /** \brief makes a link to local application, and register a prefix
   */
  shared_ptr<TopologyAppLink>
  addAppFace(const std::string& label, TopologyNode i, const Name& prefix, uint64_t cost = 0);

  /** \brief registers a prefix on a forwarder face
   */
  void
  registerPrefix(TopologyNode i, const Face& face, const Name& prefix, uint64_t cost = 0);

  /** \brief creates a producer application that answers every Interest with Data of same Name
   */
  void
  addEchoProducer(ndn::Face& face, const Name& prefix = "/");

  /** \brief creates a consumer application that sends \p n Interests under \p prefix
   *         at \p interval fixed rate.
   */
  void
  addIntervalConsumer(ndn::Face& face, const Name& prefix,
                      const time::nanoseconds& interval, size_t n);

private:
  std::vector<unique_ptr<Forwarder>> m_forwarders;
  std::vector<std::string> m_forwarderLabels;
  std::vector<shared_ptr<TopologyLink>> m_links;
  std::vector<shared_ptr<TopologyAppLink>> m_appLinks;
};

} // namespace tests
} // namespace fw
} // namespace nfd

#endif // NFD_TESTS_DAEMON_FW_TOPOLOGY_TESTER_HPP
