/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2014-2023,  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 "forwarder-general-module.hpp"
#include "format-helpers.hpp"

#include <ndn-cxx/mgmt/nfd/status-dataset.hpp>
#include <ndn-cxx/util/indented-stream.hpp>

namespace nfd::tools::nfdc {

void
ForwarderGeneralModule::fetchStatus(Controller& controller,
                                    const std::function<void()>& onSuccess,
                                    const Controller::DatasetFailCallback& onFailure,
                                    const CommandOptions& options)
{
  controller.fetch<ndn::nfd::ForwarderGeneralStatusDataset>(
    [this, onSuccess] (const ForwarderStatus& result) {
      m_status = result;
      onSuccess();
    },
    onFailure, options);
}

static auto
calculateUptime(const ForwarderStatus& status)
{
  return status.getCurrentTimestamp() - status.getStartTimestamp();
}

void
ForwarderGeneralModule::formatStatusXml(std::ostream& os) const
{
  formatItemXml(os, m_status);
}

void
ForwarderGeneralModule::formatItemXml(std::ostream& os, const ForwarderStatus& item)
{
  os << "<generalStatus>";

  os << "<version>" << xml::Text{item.getNfdVersion()} << "</version>";
  os << "<startTime>" << xml::formatTimestamp(item.getStartTimestamp()) << "</startTime>";
  os << "<currentTime>" << xml::formatTimestamp(item.getCurrentTimestamp()) << "</currentTime>";
  os << "<uptime>" << xml::formatDuration(time::duration_cast<time::seconds>(calculateUptime(item)))
     << "</uptime>";

  os << "<nNameTreeEntries>" << item.getNNameTreeEntries() << "</nNameTreeEntries>";
  os << "<nFibEntries>" << item.getNFibEntries() << "</nFibEntries>";
  os << "<nPitEntries>" << item.getNPitEntries() << "</nPitEntries>";
  os << "<nMeasurementsEntries>" << item.getNMeasurementsEntries() << "</nMeasurementsEntries>";
  os << "<nCsEntries>" << item.getNCsEntries() << "</nCsEntries>";

  os << "<packetCounters>";
  os << "<incomingPackets>"
     << "<nInterests>" << item.getNInInterests() << "</nInterests>"
     << "<nData>" << item.getNInData() << "</nData>"
     << "<nNacks>" << item.getNInNacks() << "</nNacks>"
     << "</incomingPackets>";
  os << "<outgoingPackets>"
     << "<nInterests>" << item.getNOutInterests() << "</nInterests>"
     << "<nData>" << item.getNOutData() << "</nData>"
     << "<nNacks>" << item.getNOutNacks() << "</nNacks>"
     << "</outgoingPackets>";
  os << "</packetCounters>";

  os << "<nSatisfiedInterests>" << item.getNSatisfiedInterests() << "</nSatisfiedInterests>";
  os << "<nUnsatisfiedInterests>" << item.getNUnsatisfiedInterests() << "</nUnsatisfiedInterests>";

  os << "</generalStatus>";
}

void
ForwarderGeneralModule::formatStatusText(std::ostream& os) const
{
  os << "General NFD status:\n";
  ndn::util::IndentedStream indented(os, "  ");
  formatItemText(indented, m_status);
}

void
ForwarderGeneralModule::formatItemText(std::ostream& os, const ForwarderStatus& item)
{
  text::ItemAttributes ia(true, 21);

  os << ia("version") << item.getNfdVersion()
     << ia("startTime") << text::formatTimestamp(item.getStartTimestamp())
     << ia("currentTime") << text::formatTimestamp(item.getCurrentTimestamp())
     << ia("uptime") << text::formatDuration<time::seconds>(calculateUptime(item), true);

  os << ia("nNameTreeEntries") << item.getNNameTreeEntries()
     << ia("nFibEntries") << item.getNFibEntries()
     << ia("nPitEntries") << item.getNPitEntries()
     << ia("nMeasurementsEntries") << item.getNMeasurementsEntries()
     << ia("nCsEntries") << item.getNCsEntries();

  os << ia("nInInterests") << item.getNInInterests()
     << ia("nOutInterests") << item.getNOutInterests()
     << ia("nInData") << item.getNInData()
     << ia("nOutData") << item.getNOutData()
     << ia("nInNacks") << item.getNInNacks()
     << ia("nOutNacks") << item.getNOutNacks()
     << ia("nSatisfiedInterests") << item.getNSatisfiedInterests()
     << ia("nUnsatisfiedInterests") << item.getNUnsatisfiedInterests();

  os << ia.end();
}

} // namespace nfd::tools::nfdc
