/**
 * Consumer for the NextHopFaceId test (test_nexthopfaceid)
 *
 * Author: Eric Newberry <enewberry@email.arizona.edu>
 *
 * Based on ndn-cxx example consumer
 */

#include <ndn-cxx/face.hpp>
#include <ndn-cxx/lp/nack.hpp>
#include <ndn-cxx/lp/tags.hpp>
#include <ndn-cxx/mgmt/nfd/controller.hpp>

#include <cstring>
#include <cstdlib>

using namespace ndn;

class TestNextHopFaceIdConsumer : noncopyable
{
public:
  void
  run(Name name, bool enableLocalFields, int nextHopFaceId)
  {
    nfd::ControlParameters params;
    params.setFlagBit(nfd::BIT_LOCAL_FIELDS_ENABLED, enableLocalFields);

    nfd::Controller controller(m_face, m_keyChain);
    controller.start<nfd::FaceUpdateCommand>(params,
                                             nullptr,
                                             [] (const nfd::ControlResponse& resp) {
                                               BOOST_THROW_EXCEPTION(
                                                 std::runtime_error("Unable to toggle local fields"));
                                             });
    m_face.processEvents();

    // Now, send test case Interest
    Interest interest(name);

    if (nextHopFaceId != -1) {
      interest.setTag(make_shared<lp::NextHopFaceIdTag>(nextHopFaceId));
    }

    m_face.expressInterest(interest,
                           [] (const Interest& interest, const Data& data) {
                             std::cout.write(reinterpret_cast<const char*>(data.getContent().value()),
                                             data.getContent().value_size());
                             std::cout << std::endl;
                           },
                           [] (const Interest& interest, const lp::Nack& nack) {
                             std::cout << "Nack" << std::endl;
                           },
                           [] (const Interest& interest) {
                             std::cout << "Timeout" << std::endl;
                           });
    m_face.processEvents();
  }

private:
  Face m_face;
  KeyChain m_keyChain;
};

static void
usage(const char* name)
{
  std::cerr << "Usage: " << name
            << " [prefix] [enableLocalFields - t/f] [NextHopFaceId (-1 if not set)]" << std::endl;
}

int
main(int argc, char** argv)
{
  if (argc != 4) {
    usage(argv[0]);
    return -1;
  }

  Name name(argv[1]);

  bool enableLocalFields = false;
  if (std::strcmp(argv[2], "t") == 0) {
    enableLocalFields = true;
  }
  else if (std::strcmp(argv[2], "f") == 0) {
    enableLocalFields = false;
  }
  else {
    usage(argv[0]);
    return -1;
  }

  int nextHopFaceId = std::atoi(argv[3]);

  try {
    TestNextHopFaceIdConsumer consumer;
    consumer.run(name, enableLocalFields, nextHopFaceId);
  }
  catch (const std::exception& e) {
    std::cerr << "ERROR: " << e.what() << std::endl;
    return -2;
  }

  return 0;
}
