/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2014-2021,  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 "procedure.hpp"
#include "guess-from-identity-name.hpp"
#include "guess-from-search-domains.hpp"
#include "multicast-discovery.hpp"
#include "ndn-fch-discovery.hpp"

namespace ndn {
namespace tools {
namespace autoconfig {

using nfd::ControlParameters;
using nfd::ControlResponse;

const time::nanoseconds FACEURI_CANONIZE_TIMEOUT = 4_s;
const std::vector<Name> HUB_PREFIXES{"/", "/localhop/nfd"};
const nfd::RouteOrigin HUB_ROUTE_ORIGIN = nfd::ROUTE_ORIGIN_AUTOCONF;
const uint64_t HUB_ROUTE_COST = 100;

Procedure::Procedure(Face& face, KeyChain& keyChain)
  : m_face(face)
  , m_keyChain(keyChain)
  , m_controller(face, keyChain)
{
}

void
Procedure::initialize(const Options& options)
{
  BOOST_ASSERT(m_stages.empty());
  makeStages(options);
  BOOST_ASSERT(!m_stages.empty());

  for (size_t i = 0; i < m_stages.size(); ++i) {
    m_stages[i]->onSuccess.connect([this] (const auto& uri) { connect(uri); });
    if (i + 1 < m_stages.size()) {
      m_stages[i]->onFailure.connect([=] (const auto&) { m_stages[i + 1]->start(); });
    }
    else {
      m_stages[i]->onFailure.connect([=] (const auto&) { onComplete(false); });
    }
  }
}

void
Procedure::makeStages(const Options& options)
{
  m_stages.push_back(make_unique<MulticastDiscovery>(m_face, m_controller));
  m_stages.push_back(make_unique<GuessFromSearchDomains>());
  m_stages.push_back(make_unique<NdnFchDiscovery>(options.ndnFchUrl));
  m_stages.push_back(make_unique<GuessFromIdentityName>(m_keyChain));
}

void
Procedure::runOnce()
{
  BOOST_ASSERT(!m_stages.empty());
  m_stages.front()->start();
}

void
Procedure::connect(const FaceUri& hubFaceUri)
{
  hubFaceUri.canonize(
    [this] (const FaceUri& canonicalUri) {
      m_controller.start<nfd::FaceCreateCommand>(
        ControlParameters().setUri(canonicalUri.toString()),
        [this] (const ControlParameters& params) {
          std::cerr << "Connected to HUB " << params.getUri() << std::endl;
          this->registerPrefixes(params.getFaceId());
        },
        [this, canonicalUri] (const ControlResponse& resp) {
          if (resp.getCode() == 409) {
            ControlParameters params(resp.getBody());
            std::cerr << "Already connected to HUB " << params.getUri() << std::endl;
            this->registerPrefixes(params.getFaceId());
          }
          else {
            std::cerr << "Failed to connect to HUB " << canonicalUri << ": "
                      << resp.getText() << " (" << resp.getCode() << ")" << std::endl;
            this->onComplete(false);
          }
        });
    },
    [this] (const std::string& reason) {
      std::cerr << "Failed to canonize HUB FaceUri: " << reason << std::endl;
      this->onComplete(false);
    },
    m_face.getIoService(), FACEURI_CANONIZE_TIMEOUT);
}

void
Procedure::registerPrefixes(uint64_t hubFaceId, size_t index)
{
  if (index >= HUB_PREFIXES.size()) {
    this->onComplete(true);
    return;
  }

  m_controller.start<nfd::RibRegisterCommand>(
    ControlParameters()
      .setName(HUB_PREFIXES[index])
      .setFaceId(hubFaceId)
      .setOrigin(HUB_ROUTE_ORIGIN)
      .setCost(HUB_ROUTE_COST),
    [=] (const ControlParameters&) {
      std::cerr << "Registered prefix " << HUB_PREFIXES[index] << std::endl;
      this->registerPrefixes(hubFaceId, index + 1);
    },
    [=] (const ControlResponse& resp) {
      std::cerr << "Failed to register " << HUB_PREFIXES[index] << ": "
                << resp.getText() << " (" << resp.getCode() << ")" << std::endl;
      this->onComplete(false);
    });
}

} // namespace autoconfig
} // namespace tools
} // namespace ndn
