/* -*- 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 "nfdc/status-report.hpp"

#include "status-fixture.hpp"

namespace nfd::tools::nfdc::tests {

const std::string STATUS_XML = stripXmlSpaces(R"XML(
  <?xml version="1.0"?>
  <nfdStatus xmlns="ndn:/localhost/nfd/status/1">
    <module1/>
    <module2/>
  </nfdStatus>
)XML");

const std::string STATUS_TEXT = std::string(R"TEXT(
module1
module2
)TEXT").substr(1);

class DummyModule : public Module
{
public:
  DummyModule(const std::string& moduleName, boost::asio::io_service& io)
    : m_moduleName(moduleName)
    , m_scheduler(io)
    , m_res(0)
    , m_delay(1_ms)
  {
  }

  /** \brief Cause fetchStatus() to succeed or fail.
   *  \param res zero to succeed, non-zero to fail with specific code
   *  \param delay duration from fetchStatus() invocation to succeed or fail; must be positive
   */
  void
  setResult(uint32_t res, time::nanoseconds delay)
  {
    BOOST_ASSERT(delay > 0_ns);
    m_res = res;
    m_delay = delay;
  }

  void
  fetchStatus(ndn::nfd::Controller&,
              const std::function<void()>& onSuccess,
              const ndn::nfd::DatasetFailureCallback& onFailure,
              const CommandOptions&) final
  {
    ++nFetchStatusCalls;
    m_scheduler.schedule(m_delay, [=] {
      if (m_res == 0) {
        onSuccess();
      }
      else {
        onFailure(m_res, m_moduleName + " fails with code " + to_string(m_res));
      }
    });
  }

  void
  formatStatusXml(std::ostream& os) const final
  {
    os << '<' << m_moduleName << "/>";
  }

  void
  formatStatusText(std::ostream& os) const final
  {
    os << m_moduleName << '\n';
  }

public:
  int nFetchStatusCalls = 0;

private:
  std::string m_moduleName;
  Scheduler m_scheduler;
  uint32_t m_res;
  time::nanoseconds m_delay;
};

class StatusReportTester : public StatusReport
{
private:
  void
  processEvents(Face&) override
  {
    processEventsFunc();
  }

public:
  std::function<void()> processEventsFunc;
};

class StatusReportModulesFixture : public nfd::tests::IoFixture, public nfd::tests::KeyChainFixture
{
protected:
  StatusReportModulesFixture()
    : face(m_io, m_keyChain)
    , controller(face, m_keyChain, validator)
    , res(0)
  {
  }

  DummyModule&
  addModule(const std::string& moduleName)
  {
    report.sections.push_back(make_unique<DummyModule>(moduleName, m_io));
    return static_cast<DummyModule&>(*report.sections.back());
  }

  void
  collect(time::nanoseconds tick, size_t nTicks)
  {
    report.processEventsFunc = [=] { advanceClocks(tick, nTicks); };
    res = report.collect(face, m_keyChain, validator, CommandOptions());

    if (res == 0) {
      statusXml.str("");
      report.formatXml(statusXml);
      statusText.str("");
      report.formatText(statusText);
    }
  }

protected:
  ndn::DummyClientFace face;
  ValidatorNull validator;
  ndn::nfd::Controller controller;
  StatusReportTester report;

  uint32_t res;
  output_test_stream statusXml;
  output_test_stream statusText;
};

BOOST_AUTO_TEST_SUITE(Nfdc)
BOOST_FIXTURE_TEST_SUITE(TestStatusReport, StatusReportModulesFixture)

BOOST_AUTO_TEST_CASE(Normal)
{
  DummyModule& m1 = addModule("module1");
  m1.setResult(0, 10_ms);
  DummyModule& m2 = addModule("module2");
  m2.setResult(0, 20_ms);

  this->collect(5_ms, 6);

  BOOST_CHECK_EQUAL(m1.nFetchStatusCalls, 1);
  BOOST_CHECK_EQUAL(m2.nFetchStatusCalls, 1);

  BOOST_CHECK_EQUAL(res, 0);
  BOOST_CHECK(statusXml.is_equal(STATUS_XML));
  BOOST_CHECK(statusText.is_equal(STATUS_TEXT));
}

BOOST_AUTO_TEST_CASE(Reorder)
{
  DummyModule& m1 = addModule("module1");
  m1.setResult(0, 20_ms);
  DummyModule& m2 = addModule("module2");
  m2.setResult(0, 10_ms); // module2 completes earlier than module1

  this->collect(5_ms, 6);

  BOOST_CHECK_EQUAL(res, 0);
  BOOST_CHECK(statusXml.is_equal(STATUS_XML)); // output is still in order
  BOOST_CHECK(statusText.is_equal(STATUS_TEXT));
}

BOOST_AUTO_TEST_CASE(Error)
{
  DummyModule& m1 = addModule("module1");
  m1.setResult(0, 20_ms);
  DummyModule& m2 = addModule("module2");
  m2.setResult(500, 10_ms);

  this->collect(5_ms, 6);

  BOOST_CHECK_EQUAL(res, 1000500);
}

BOOST_AUTO_TEST_SUITE_END() // TestStatusReport
BOOST_AUTO_TEST_SUITE_END() // Nfdc

} // namespace nfd::tools::nfdc::tests
