/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
/**
 * Copyright (C) 2013 Regents of the University of California.
 * See COPYING for copyright and distribution information.
 */

#include "common.hpp"
#include "../face.hpp"

// NRD
#include "nrd-controller.hpp"
#include "nrd-prefix-reg-options.hpp"

// NFD
#include "nfd-control-response.hpp"

namespace ndn {
namespace nrd {

Controller::Controller(Face& face)
  : m_face(face)
  , m_faceId(0)
{
}

void
Controller::selfRegisterPrefix(const Name& prefixToRegister,
                               const SuccessCallback& onSuccess,
                               const FailCallback&    onFail)
{
  startCommand("register",
               PrefixRegOptions()
                 .setName(prefixToRegister)
                 .setFaceId(0) // self-registration
                 .setCost(0),
               bind(&Controller::recordSelfRegisteredFaceId, this, _1, onSuccess),
               onFail);
}

void
Controller::selfDeregisterPrefix(const Name& prefixToRegister,
                                 const SuccessCallback& onSuccess,
                                 const FailCallback&    onFail)
{
  if (m_faceId == 0)
    {
      if (static_cast<bool>(onFail))
        onFail("Face ID is not set, should have been set after a successful prefix registration command");
      return;
    }

  startCommand("unregister",
               PrefixRegOptions()
                 .setName(prefixToRegister)
                 .setFaceId(m_faceId),
               bind(onSuccess), onFail);
}

void
Controller::startCommand(const std::string& command,
                         const PrefixRegOptions& options,
                         const CommandSucceedCallback& onSuccess,
                         const FailCallback& onFail)
{
  Name commandInterestName("/localhost/nrd");
  commandInterestName
    .append(command)
    .append(options.wireEncode());

  Interest commandInterest(commandInterestName);
  // m_keyChain.sign(commandInterest);

  m_face.expressInterest(commandInterest,
                         bind(&Controller::processCommandResponse, this, _2,
                              onSuccess, onFail),
                         bind(onFail, "Command Interest timed out"));
}

void
Controller::recordSelfRegisteredFaceId(const PrefixRegOptions& entry,
                                       const SuccessCallback& onSuccess)
{
  m_faceId = entry.getFaceId();
  onSuccess();
}

void
Controller::processCommandResponse(Data& data,
                                   const CommandSucceedCallback& onSuccess,
                                   const FailCallback& onFail)
{
  try
    {
      nfd::ControlResponse response(data.getContent().blockFromValue());
      if (response.getCode() != 200)
        return onFail(response.getText());

      PrefixRegOptions options(response.getBody());
      return onSuccess(options);
    }
  catch(ndn::Tlv::Error& e)
    {
      if (static_cast<bool>(onFail))
        return onFail(e.what());
    }
}

} // namespace nrd
} // namespace ndn
