/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2014-2017,  The University of Memphis,
 *                           Regents of the University of California
 *
 * This file is part of NLSR (Named-data Link State Routing).
 * See AUTHORS.md for complete list of NLSR authors and contributors.
 *
 * NLSR 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.
 *
 * NLSR 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
 * NLSR, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
 *
 **/

#include "face-controller.hpp"

#include "common.hpp"
#include "logger.hpp"

namespace nlsr {
namespace util {

INIT_LOGGER("FaceController");

using ndn::util::FaceUri;

const ndn::time::seconds FaceController::TIME_ALLOWED_FOR_CANONIZATION = ndn::time::seconds(4);

void
FaceController::createFace(const std::string& request,
                           const CommandSuccessCallback& onSuccess,
                           const CommandFailureCallback& onFailure)
{
  FaceUri uri(request);

  _LOG_TRACE("Converting " << uri << " to canonical form");
  uri.canonize(std::bind(&FaceController::onCanonizeSuccess, this, _1, onSuccess, onFailure, uri),
               std::bind(&FaceController::onCanonizeFailure, this, _1, onSuccess, onFailure, uri),
               m_ioService, TIME_ALLOWED_FOR_CANONIZATION);
}

void
FaceController::createFaceInNfd(const FaceUri& uri,
                                const CommandSuccessCallback& onSuccess,
                                const CommandFailureCallback& onFailure)
{
  ndn::nfd::ControlParameters faceParameters;
  faceParameters.setUri(uri.toString());

  _LOG_DEBUG("Creating Face in NFD with face-uri: " << uri);
  m_controller.start<ndn::nfd::FaceCreateCommand>(faceParameters, onSuccess,
                                                  [onSuccess, onFailure, uri] (const ndn::nfd::ControlResponse& response) {
                                                    ndn::nfd::ControlParameters faceParams(response.getBody());
                                                    if (response.getCode() == 409 && faceParams.getUri() == uri.toString()) {
                                                      _LOG_DEBUG("Got 409 - treating as success");
                                                      onSuccess(faceParams);
                                                    }
                                                    else {
                                                      onFailure(response);
                                                    }
                                                  }
                                                 );
}

void
FaceController::onCanonizeSuccess(const FaceUri& uri,
                                  const CommandSuccessCallback& onSuccess,
                                  const CommandFailureCallback& onFailure,
                                  const FaceUri& request)
{
  _LOG_DEBUG("Converted " << request << " to canonical form: " << uri);

  createFaceInNfd(uri, onSuccess, onFailure);
}

void
FaceController::onCanonizeFailure(const std::string& reason,
                                  const CommandSuccessCallback& onSuccess,
                                  const CommandFailureCallback& onFailure,
                                  const FaceUri& request)
{
  _LOG_WARN("Could not convert " << request << " to canonical form: " << reason);
  onFailure(ndn::nfd::ControlResponse(CANONIZE_ERROR_CODE,
                                      "Could not canonize face-uri: " + request.toString()));
}

} // namespace util
} // namespace nlsr
