/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2014-2024,  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 "multicast-discovery.hpp"

#include <boost/lexical_cast.hpp>

#include <ndn-cxx/encoding/tlv-nfd.hpp>
#include <ndn-cxx/mgmt/nfd/status-dataset.hpp>

namespace ndn::autoconfig {

using nfd::ControlParameters;

const Name HUB_DISCOVERY_PREFIX{"/localhop/ndn-autoconf/hub"};
constexpr uint64_t HUB_DISCOVERY_ROUTE_COST = 1;
constexpr time::milliseconds HUB_DISCOVERY_ROUTE_EXPIRATION = 30_s;
constexpr time::milliseconds HUB_DISCOVERY_INTEREST_LIFETIME = 4_s;

MulticastDiscovery::MulticastDiscovery(Face& face, nfd::Controller& controller)
  : m_face(face)
  , m_controller(controller)
{
}

void
MulticastDiscovery::doStart()
{
  nfd::FaceQueryFilter filter;
  filter.setLinkType(nfd::LINK_TYPE_MULTI_ACCESS);

  m_controller.fetch<nfd::FaceQueryDataset>(
    filter,
    [this] (const auto& dataset) { registerHubDiscoveryPrefix(dataset); },
    [this] (uint32_t code, const std::string& reason) {
      fail("Error " + std::to_string(code) + " when querying multi-access faces: " + reason);
    });
}

void
MulticastDiscovery::registerHubDiscoveryPrefix(const std::vector<nfd::FaceStatus>& dataset)
{
  if (dataset.empty()) {
    fail("No multi-access faces available");
    return;
  }

  m_nRegs = dataset.size();
  m_nRegSuccess = 0;
  m_nRegFailure = 0;

  for (const auto& faceStatus : dataset) {
    ControlParameters parameters;
    parameters.setName(HUB_DISCOVERY_PREFIX)
              .setFaceId(faceStatus.getFaceId())
              .setCost(HUB_DISCOVERY_ROUTE_COST)
              .setExpirationPeriod(HUB_DISCOVERY_ROUTE_EXPIRATION);

    m_controller.start<nfd::RibRegisterCommand>(
      parameters,
      [this] (const auto&) {
        ++m_nRegSuccess;
        afterReg();
      },
      [this, faceStatus] (const auto& resp) {
        std::cerr << "Error " << resp.getCode() << " when registering hub discovery prefix "
                  << "for face " << faceStatus.getFaceId() << " (" << faceStatus.getRemoteUri()
                  << "): " << resp.getText() << std::endl;
        ++m_nRegFailure;
        afterReg();
      });
  }
}

void
MulticastDiscovery::afterReg()
{
  if (m_nRegSuccess + m_nRegFailure < m_nRegs) {
    return; // continue waiting
  }
  if (m_nRegSuccess > 0) {
    setStrategy();
  }
  else {
    fail("Cannot register hub discovery prefix for any face");
  }
}

void
MulticastDiscovery::setStrategy()
{
  ControlParameters parameters;
  parameters.setName(HUB_DISCOVERY_PREFIX)
            .setStrategy("/localhost/nfd/strategy/multicast");

  m_controller.start<nfd::StrategyChoiceSetCommand>(
    parameters,
    [this] (const auto&) { requestHubData(); },
    [this] (const auto& resp) {
      fail("Error " + std::to_string(resp.getCode()) + " when setting multicast strategy: " + resp.getText());
    });
}

void
MulticastDiscovery::requestHubData()
{
  Interest interest(HUB_DISCOVERY_PREFIX);
  interest.setCanBePrefix(true);
  interest.setMustBeFresh(true);
  interest.setInterestLifetime(HUB_DISCOVERY_INTEREST_LIFETIME);

  m_face.expressInterest(interest,
    [this] (const Interest&, const Data& data) {
      const Block& content = data.getContent();
      content.parse();

      auto i = content.find(tlv::nfd::Uri);
      if (i == content.elements_end()) {
        fail("Malformed hub Data: missing Uri element");
        return;
      }

      provideHubFaceUri(std::string(reinterpret_cast<const char*>(i->value()), i->value_size()));
    },
    [this] (const Interest&, const lp::Nack& nack) {
      fail("Nack-" + boost::lexical_cast<std::string>(nack.getReason()) + " when retrieving hub Data");
    },
    [this] (const Interest&) {
      fail("Timeout when retrieving hub Data");
    });
}

} // namespace ndn::autoconfig
