/* -*- 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/>.
 *
 * @author Jerald Paul Abraham <jeraldabraham@email.arizona.edu>
 */

#include "version.hpp"

#include <ndn-cxx/face.hpp>
#include <ndn-cxx/name.hpp>
#include <ndn-cxx/interest.hpp>
#include <ndn-cxx/encoding/buffer-stream.hpp>

#include <ndn-cxx/management/nfd-forwarder-status.hpp>
#include <ndn-cxx/management/nfd-channel-status.hpp>
#include <ndn-cxx/management/nfd-face-status.hpp>
#include <ndn-cxx/management/nfd-fib-entry.hpp>
#include <ndn-cxx/management/nfd-strategy-choice.hpp>

#include <boost/algorithm/string/replace.hpp>
#include <list>

namespace ndn {

class NfdStatus
{
public:
  explicit
  NfdStatus(char* toolName)
    : m_toolName(toolName)
    , m_needVersionRetrieval(false)
    , m_needChannelStatusRetrieval(false)
    , m_needFaceStatusRetrieval(false)
    , m_needFibEnumerationRetrieval(false)
    , m_needStrategyChoiceRetrieval(false)
    , m_isOutputXml(false)
  {
  }

  void
  usage()
  {
    std::cout << "Usage: \n  " << m_toolName << " [options]\n\n"
      "Show NFD version and status information\n\n"
      "Options:\n"
      "  [-h] - print this help message\n"
      "  [-v] - retrieve version information\n"
      "  [-c] - retrieve channel status information\n"
      "  [-f] - retrieve face status information\n"
      "  [-b] - retrieve FIB information\n"
      "  [-s] - retrieve configured strategy choice for NDN namespaces\n"
      "  [-x] - retrieve NFD status information in XML format\n"
      "\n"
      "  [-V] - show version information of nfd-status and exit\n"
      "\n"
      "If no options are provided, all information is retrieved.\n"
      "If -x is provided, other options(v, f and b) are ignored, and all information is retrieved in XML format.\n"
      ;
  }

  void
  enableVersionRetrieval()
  {
    m_needVersionRetrieval = true;
  }

  void
  enableChannelStatusRetrieval()
  {
    m_needChannelStatusRetrieval = true;
  }

  void
  enableFaceStatusRetrieval()
  {
    m_needFaceStatusRetrieval = true;
  }

  void
  enableFibEnumerationRetrieval()
  {
    m_needFibEnumerationRetrieval = true;
  }

  void
  enableStrategyChoiceRetrieval()
  {
    m_needStrategyChoiceRetrieval = true;
  }

  void
  enableXmlOutput()
  {
    m_isOutputXml = true;
  }

  void
  onTimeout()
  {
    std::cerr << "Request timed out" << std::endl;

    runNextStep();
  }

  void
  fetchSegments(const Data& data, void (NfdStatus::*onDone)())
  {
    m_buffer->write((const char*)data.getContent().value(),
                    data.getContent().value_size());

    uint64_t currentSegment = data.getName().get(-1).toSegment();

    const name::Component& finalBlockId = data.getMetaInfo().getFinalBlockId();
    if (finalBlockId.empty() ||
        finalBlockId.toSegment() > currentSegment)
      {
        m_face.expressInterest(data.getName().getPrefix(-1).appendSegment(currentSegment+1),
                               bind(&NfdStatus::fetchSegments, this, _2, onDone),
                               bind(&NfdStatus::onTimeout, this));
      }
    else
      {
        return (this->*onDone)();
      }
  }

  void
  escapeSpecialCharacters(std::string *data)
  {
    using boost::algorithm::replace_all;
    replace_all(*data, "&",  "&amp;");
    replace_all(*data, "\"", "&quot;");
    replace_all(*data, "\'", "&apos;");
    replace_all(*data, "<",  "&lt;");
    replace_all(*data, ">",  "&gt;");
  }

  //////////////////////////////////////////////////////////////////////////////////
  //////////////////////////////////////////////////////////////////////////////////

  void
  fetchVersionInformation()
  {
    Interest interest("/localhost/nfd/status");
    interest.setChildSelector(1);
    interest.setMustBeFresh(true);
    m_face.expressInterest(
                           interest,
                           bind(&NfdStatus::afterFetchedVersionInformation, this, _2),
                           bind(&NfdStatus::onTimeout, this));
  }

  void
  afterFetchedVersionInformation(const Data& data)
  {
    nfd::ForwarderStatus status(data.getContent());
    if (m_isOutputXml)
      {
        std::cout << "<generalStatus>";
        std::cout << "<version>"
                  << status.getNfdVersion() << "</version>";
        std::cout << "<startTime>"
                  << time::toString(status.getStartTimestamp(), "%Y-%m-%dT%H:%M:%S%F")
                  << "</startTime>";
        std::cout << "<currentTime>"
                  << time::toString(status.getCurrentTimestamp(), "%Y-%m-%dT%H:%M:%S%F")
                  << "</currentTime>";
        std::cout << "<uptime>PT"
                  << time::duration_cast<time::seconds>(status.getCurrentTimestamp()
                                                        - status.getStartTimestamp()).count()
                  << "S</uptime>";
        std::cout << "<nNameTreeEntries>"     << status.getNNameTreeEntries()
                  << "</nNameTreeEntries>";
        std::cout << "<nFibEntries>"          << status.getNFibEntries()
                  << "</nFibEntries>";
        std::cout << "<nPitEntries>"          << status.getNPitEntries()
                  << "</nPitEntries>";
        std::cout << "<nMeasurementsEntries>" << status.getNMeasurementsEntries()
                  << "</nMeasurementsEntries>";
        std::cout << "<nCsEntries>"           << status.getNCsEntries()
                  << "</nCsEntries>";
        std::cout << "<packetCounters>";
        std::cout << "<incomingPackets>";
        std::cout << "<nInterests>"           << status.getNInInterests()
                  << "</nInterests>";
        std::cout << "<nDatas>"               << status.getNInDatas()
                  << "</nDatas>";
        std::cout << "</incomingPackets>";
        std::cout << "<outgoingPackets>";
        std::cout << "<nInterests>"           << status.getNOutInterests()
                  << "</nInterests>";
        std::cout << "<nDatas>"               << status.getNOutDatas()
                  << "</nDatas>";
        std::cout << "</outgoingPackets>";
        std::cout << "</packetCounters>";
        std::cout << "</generalStatus>";
      }
    else
      {
        std::cout << "General NFD status:" << std::endl;
        std::cout << "               version="
                  << status.getNfdVersion() << std::endl;
        std::cout << "             startTime="
                  << time::toIsoString(status.getStartTimestamp()) << std::endl;
        std::cout << "           currentTime="
                  << time::toIsoString(status.getCurrentTimestamp()) << std::endl;
        std::cout << "                uptime="
                  << time::duration_cast<time::seconds>(status.getCurrentTimestamp()
                                                        - status.getStartTimestamp()) << std::endl;

        std::cout << "      nNameTreeEntries=" << status.getNNameTreeEntries()     << std::endl;
        std::cout << "           nFibEntries=" << status.getNFibEntries()          << std::endl;
        std::cout << "           nPitEntries=" << status.getNPitEntries()          << std::endl;
        std::cout << "  nMeasurementsEntries=" << status.getNMeasurementsEntries() << std::endl;
        std::cout << "            nCsEntries=" << status.getNCsEntries()           << std::endl;
        std::cout << "          nInInterests=" << status.getNInInterests()         << std::endl;
        std::cout << "         nOutInterests=" << status.getNOutInterests()        << std::endl;
        std::cout << "              nInDatas=" << status.getNInDatas()             << std::endl;
        std::cout << "             nOutDatas=" << status.getNOutDatas()            << std::endl;
      }

    runNextStep();
  }

  //////////////////////////////////////////////////////////////////////////////////
  //////////////////////////////////////////////////////////////////////////////////

  void
  fetchChannelStatusInformation()
  {
    m_buffer = make_shared<OBufferStream>();

    Interest interest("/localhost/nfd/faces/channels");
    interest.setChildSelector(1);
    interest.setMustBeFresh(true);

    m_face.expressInterest(interest,
                           bind(&NfdStatus::fetchSegments, this, _2,
                                &NfdStatus::afterFetchedChannelStatusInformation),
                           bind(&NfdStatus::onTimeout, this));
  }

  void
  afterFetchedChannelStatusInformation()
  {
    ConstBufferPtr buf = m_buffer->buf();
    if (m_isOutputXml)
      {
        std::cout << "<channels>";

        Block block;
        size_t offset = 0;
        while (offset < buf->size())
          {
            bool ok = Block::fromBuffer(buf, offset, block);
            if (!ok)
              {
                std::cerr << "ERROR: cannot decode ChannelStatus TLV" << std::endl;
                break;
              }

            offset += block.size();

            nfd::ChannelStatus channelStatus(block);

            std::cout << "<channel>";

            std::string localUri(channelStatus.getLocalUri());
            escapeSpecialCharacters(&localUri);
            std::cout << "<localUri>" << localUri << "</localUri>";
            std::cout << "</channel>";
          }
        std::cout << "</channels>";
      }
    else
      {
        std::cout << "Channels:" << std::endl;

        Block block;
        size_t offset = 0;
        while (offset < buf->size())
          {
            bool ok = Block::fromBuffer(buf, offset, block);
            if (!ok)
              {
                std::cerr << "ERROR: cannot decode ChannelStatus TLV" << std::endl;
                break;
              }

            offset += block.size();

            nfd::ChannelStatus channelStatus(block);
            std::cout << "  " << channelStatus.getLocalUri() << std::endl;
          }
       }

    runNextStep();
  }

  //////////////////////////////////////////////////////////////////////////////////
  //////////////////////////////////////////////////////////////////////////////////

  void
  fetchFaceStatusInformation()
  {
    m_buffer = make_shared<OBufferStream>();

    Interest interest("/localhost/nfd/faces/list");
    interest.setChildSelector(1);
    interest.setMustBeFresh(true);

    m_face.expressInterest(interest,
                           bind(&NfdStatus::fetchSegments, this, _2,
                                &NfdStatus::afterFetchedFaceStatusInformation),
                           bind(&NfdStatus::onTimeout, this));
  }

  void
  afterFetchedFaceStatusInformation()
  {
    ConstBufferPtr buf = m_buffer->buf();
    if (m_isOutputXml)
      {
        std::cout << "<faces>";

        Block block;
        size_t offset = 0;
        while (offset < buf->size())
          {
            bool ok = Block::fromBuffer(buf, offset, block);
            if (!ok)
              {
                std::cerr << "ERROR: cannot decode FaceStatus TLV" << std::endl;
                break;
              }

            offset += block.size();

            nfd::FaceStatus faceStatus(block);

            std::cout << "<face>";
            std::cout << "<faceId>" << faceStatus.getFaceId() << "</faceId>";

            std::string remoteUri(faceStatus.getRemoteUri());
            escapeSpecialCharacters(&remoteUri);
            std::cout << "<remoteUri>" << remoteUri << "</remoteUri>";

            std::string localUri(faceStatus.getLocalUri());
            escapeSpecialCharacters(&localUri);
            std::cout << "<localUri>" << localUri << "</localUri>";
            std::cout << "<packetCounters>";
            std::cout << "<incomingPackets>";
            std::cout << "<nInterests>"       << faceStatus.getNInInterests()
                      << "</nInterests>";
            std::cout << "<nDatas>"           << faceStatus.getNInInterests()
                      << "</nDatas>";
            std::cout << "</incomingPackets>";
            std::cout << "<outgoingPackets>";
            std::cout << "<nInterests>"       << faceStatus.getNOutInterests()
                      << "</nInterests>";
            std::cout << "<nDatas>"           << faceStatus.getNOutInterests()
                      << "</nDatas>";
            std::cout << "</outgoingPackets>";
            std::cout << "</packetCounters>";
            std::cout << "</face>";
          }
        std::cout << "</faces>";
      }
    else
      {
        std::cout << "Faces:" << std::endl;

        Block block;
        size_t offset = 0;
        while (offset < buf->size())
          {
            bool ok = Block::fromBuffer(buf, offset, block);
            if (!ok)
              {
                std::cerr << "ERROR: cannot decode FaceStatus TLV" << std::endl;
                break;
              }

            offset += block.size();

            nfd::FaceStatus faceStatus(block);

            std::cout << "  faceid=" << faceStatus.getFaceId()
                      << " remote=" << faceStatus.getRemoteUri()
                      << " local=" << faceStatus.getLocalUri()
                      << " counters={"
                      << "in={" << faceStatus.getNInInterests() << "i "
                      << faceStatus.getNInDatas() << "d}"
                      << " out={" << faceStatus.getNOutInterests() << "i "
                      << faceStatus.getNOutDatas() << "d}"
                      << "}" << std::endl;
          }
       }

    runNextStep();
  }

  //////////////////////////////////////////////////////////////////////////////////
  //////////////////////////////////////////////////////////////////////////////////

  void
  fetchFibEnumerationInformation()
  {
    m_buffer = make_shared<OBufferStream>();

    Interest interest("/localhost/nfd/fib/list");
    interest.setChildSelector(1);
    interest.setMustBeFresh(true);
    m_face.expressInterest(interest,
                           bind(&NfdStatus::fetchSegments, this, _2,
                                &NfdStatus::afterFetchedFibEnumerationInformation),
                           bind(&NfdStatus::onTimeout, this));
  }

  void
  afterFetchedFibEnumerationInformation()
  {
    ConstBufferPtr buf = m_buffer->buf();
    if (m_isOutputXml)
      {
        std::cout << "<fib>";

        Block block;
        size_t offset = 0;
        while (offset < buf->size())
          {
            bool ok = Block::fromBuffer(buf, offset, block);
            if (!ok)
              {
                std::cerr << "ERROR: cannot decode FibEntry TLV";
                break;
              }
            offset += block.size();

            nfd::FibEntry fibEntry(block);

            std::cout << "<fibEntry>";
            std::string prefix(fibEntry.getPrefix().toUri());
            escapeSpecialCharacters(&prefix);
            std::cout << "<prefix>" << prefix << "</prefix>";
            std::cout << "<nextHops>";
            for (std::list<nfd::NextHopRecord>::const_iterator
                   nextHop = fibEntry.getNextHopRecords().begin();
                 nextHop != fibEntry.getNextHopRecords().end();
                 ++nextHop)
              {
                std::cout << "<nextHop>" ;
                std::cout << "<faceId>"  << nextHop->getFaceId() << "</faceId>";
                std::cout << "<cost>"    << nextHop->getCost()   << "</cost>";
                std::cout << "</nextHop>";
              }
            std::cout << "</nextHops>";
            std::cout << "</fibEntry>";
          }

        std::cout << "</fib>";
      }
    else
      {
        std::cout << "FIB:" << std::endl;

        Block block;
        size_t offset = 0;
        while (offset < buf->size())
          {
            bool ok = Block::fromBuffer(buf, offset, block);
            if (!ok)
              {
                std::cerr << "ERROR: cannot decode FibEntry TLV" << std::endl;
                break;
              }
            offset += block.size();

            nfd::FibEntry fibEntry(block);

            std::cout << "  " << fibEntry.getPrefix() << " nexthops={";
            for (std::list<nfd::NextHopRecord>::const_iterator
                   nextHop = fibEntry.getNextHopRecords().begin();
                 nextHop != fibEntry.getNextHopRecords().end();
                 ++nextHop)
              {
                if (nextHop != fibEntry.getNextHopRecords().begin())
                  std::cout << ", ";
                std::cout << "faceid=" << nextHop->getFaceId()
                          << " (cost=" << nextHop->getCost() << ")";
              }
            std::cout << "}" << std::endl;
          }
      }

    runNextStep();
  }

  //////////////////////////////////////////////////////////////////////////////////
  //////////////////////////////////////////////////////////////////////////////////

  void
  fetchStrategyChoiceInformation()
  {
    m_buffer = make_shared<OBufferStream>();

    Interest interest("/localhost/nfd/strategy-choice/list");
    interest.setChildSelector(1);
    interest.setMustBeFresh(true);
    m_face.expressInterest(interest,
                           bind(&NfdStatus::fetchSegments, this, _2,
                                &NfdStatus::afterFetchedStrategyChoiceInformationInformation),
                           bind(&NfdStatus::onTimeout, this));
  }

  void
  afterFetchedStrategyChoiceInformationInformation()
  {
    ConstBufferPtr buf = m_buffer->buf();
    if (m_isOutputXml)
      {
        std::cout << "<strategyChoices>";

        Block block;
        size_t offset = 0;
        while (offset < buf->size())
          {
            bool ok = Block::fromBuffer(buf, offset, block);
            if (!ok)
              {
                std::cerr << "ERROR: cannot decode StrategyChoice TLV";
                break;
              }
            offset += block.size();

            nfd::StrategyChoice strategyChoice(block);

            std::cout << "<strategyChoice>";

            std::string name(strategyChoice.getName().toUri());
            escapeSpecialCharacters(&name);
            std::cout << "<namespace>" << name << "</namespace>";
            std::cout << "<strategy>";

            std::string strategy(strategyChoice.getStrategy().toUri());
            escapeSpecialCharacters(&strategy);

            std::cout << "<name>" << strategy << "</name>";
            std::cout << "</strategy>";
            std::cout << "</strategyChoice>";
          }

        std::cout << "</strategyChoices>";
      }
    else
      {
        std::cout << "Strategy choices:" << std::endl;

        Block block;
        size_t offset = 0;
        while (offset < buf->size())
          {
            bool ok = Block::fromBuffer(buf, offset, block);
            if (!ok)
              {
                std::cerr << "ERROR: cannot decode StrategyChoice TLV" << std::endl;
                break;
              }
            offset += block.size();

            nfd::StrategyChoice strategyChoice(block);

            std::cout << "  " << strategyChoice.getName()
                      << " strategy=" << strategyChoice.getStrategy() << std::endl;
          }
      }

    runNextStep();
  }

  void
  fetchInformation()
  {
    if (m_isOutputXml ||
        (!m_needVersionRetrieval &&
         !m_needChannelStatusRetrieval &&
         !m_needFaceStatusRetrieval &&
         !m_needFibEnumerationRetrieval &&
         !m_needStrategyChoiceRetrieval))
      {
        enableVersionRetrieval();
        enableChannelStatusRetrieval();
        enableFaceStatusRetrieval();
        enableFibEnumerationRetrieval();
        enableStrategyChoiceRetrieval();
      }

    if (m_isOutputXml)
      m_fetchSteps.push_back(bind(&NfdStatus::printXmlHeader, this));

    if (m_needVersionRetrieval)
      m_fetchSteps.push_back(bind(&NfdStatus::fetchVersionInformation, this));

    if (m_needChannelStatusRetrieval)
      m_fetchSteps.push_back(bind(&NfdStatus::fetchChannelStatusInformation, this));

    if (m_needFaceStatusRetrieval)
      m_fetchSteps.push_back(bind(&NfdStatus::fetchFaceStatusInformation, this));

    if (m_needFibEnumerationRetrieval)
      m_fetchSteps.push_back(bind(&NfdStatus::fetchFibEnumerationInformation, this));

    if (m_needStrategyChoiceRetrieval)
      m_fetchSteps.push_back(bind(&NfdStatus::fetchStrategyChoiceInformation, this));

    if (m_isOutputXml)
      m_fetchSteps.push_back(bind(&NfdStatus::printXmlFooter, this));

    runNextStep();
    m_face.processEvents();
  }

private:
  void
  printXmlHeader()
  {
    std::cout << "<?xml version=\"1.0\"?>";
    std::cout << "<nfdStatus xmlns=\"ndn:/localhost/nfd/status/1\">";

    runNextStep();
  }

  void
  printXmlFooter()
  {
    std::cout << "</nfdStatus>";

    runNextStep();
  }

  void
  runNextStep()
  {
    if (m_fetchSteps.empty())
      return;

    function<void()> nextStep = m_fetchSteps.front();
    m_fetchSteps.pop_front();
    nextStep();
  }

private:
  std::string m_toolName;
  bool m_needVersionRetrieval;
  bool m_needChannelStatusRetrieval;
  bool m_needFaceStatusRetrieval;
  bool m_needFibEnumerationRetrieval;
  bool m_needStrategyChoiceRetrieval;
  bool m_isOutputXml;
  Face m_face;

  shared_ptr<OBufferStream> m_buffer;

  std::deque<function<void()> > m_fetchSteps;
};

}

int main(int argc, char* argv[])
{
  int option;
  ndn::NfdStatus nfdStatus(argv[0]);

  while ((option = getopt(argc, argv, "hvcfbsxV")) != -1) {
    switch (option) {
    case 'h':
      nfdStatus.usage();
      return 0;
    case 'v':
      nfdStatus.enableVersionRetrieval();
      break;
    case 'c':
      nfdStatus.enableChannelStatusRetrieval();
      break;
    case 'f':
      nfdStatus.enableFaceStatusRetrieval();
      break;
    case 'b':
      nfdStatus.enableFibEnumerationRetrieval();
      break;
    case 's':
      nfdStatus.enableStrategyChoiceRetrieval();
      break;
    case 'x':
      nfdStatus.enableXmlOutput();
      break;
    case 'V':
      std::cout << NFD_VERSION_BUILD_STRING << std::endl;
      return 0;
    default:
      nfdStatus.usage();
      return 1;
    }
  }

  try {
    nfdStatus.fetchInformation();
  }
  catch (std::exception& e) {
    std::cerr << "ERROR: " << e.what() << std::endl;
    return 2;
  }

  return 0;
}
