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

#include "core/face-uri.hpp"

#include <ndn-cxx/face.hpp>
#include <ndn-cxx/management/nfd-controller.hpp>
#include <ndn-cxx/management/nfd-face-status.hpp>
#include <ndn-cxx/security/key-chain.hpp>
#include <ndn-cxx/encoding/buffer-stream.hpp>

#include <boost/lexical_cast.hpp>

#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/nameser.h>
#include <resolv.h>

#ifdef __APPLE__
#include <arpa/nameser_compat.h>
#endif

namespace ndn {
namespace tools {

void
usage(const char* programName)
{
  std::cout << "Usage:\n" << programName  << " [-h] [-V]\n"
            << "   -h  - print usage and exit\n"
            << "   -V  - print version number and exit\n"
            << std::endl;
}

class NdnAutoconfig
{
public:
  union QueryAnswer
  {
    HEADER header;
    uint8_t buf[NS_PACKETSZ];
  };

  class Error : public std::runtime_error
  {
  public:
    explicit
    Error(const std::string& what)
      : std::runtime_error(what)
    {
    }
  };

  explicit
  NdnAutoconfig()
    : m_controller(m_face)
  {
  }

  void
  run()
  {
    m_face.processEvents();
  }

  void
  fetchSegments(const Data& data, const shared_ptr<OBufferStream>& buffer,
                void (NdnAutoconfig::*onDone)(const shared_ptr<OBufferStream>&))
  {
    buffer->write(reinterpret_cast<const char*>(data.getContent().value()),
                  data.getContent().value_size());

    uint64_t currentSegment = data.getName().get(-1).toSegment();

    const name::Component& finalBlockId = data.getMetaInfo().getFinalBlockId();
    if (finalBlockId.empty() ||
        finalBlockId.toSegment() > currentSegment)
      {
        m_face.expressInterest(data.getName().getPrefix(-1).appendSegment(currentSegment+1),
                               bind(&NdnAutoconfig::fetchSegments, this, _2, buffer, onDone),
                               bind(&NdnAutoconfig::discoverHubStage2, this, "Timeout"));
      }
    else
      {
        return (this->*onDone)(buffer);
      }
  }

  void
  discoverHubStage1()
  {
    shared_ptr<OBufferStream> buffer = make_shared<OBufferStream>();

    Interest interest("/localhost/nfd/faces/list");
    interest.setChildSelector(1);
    interest.setMustBeFresh(true);

    m_face.expressInterest(interest,
                           bind(&NdnAutoconfig::fetchSegments, this, _2, buffer,
                                &NdnAutoconfig::discoverHubStage1_registerLocalhubNdnAutoconfHub),
                           bind(&NdnAutoconfig::discoverHubStage2, this, "Timeout"));
  }

  void
  discoverHubStage1_registerLocalhubNdnAutoconfHub(const shared_ptr<OBufferStream>& buffer)
  {
    ConstBufferPtr buf = buffer->buf();
    std::vector<uint64_t> multicastFaces;

    size_t offset = 0;
    while (offset < buf->size())
      {
        Block block;
        bool ok = Block::fromBuffer(buf, offset, block);
        if (!ok)
          {
            std::cerr << "ERROR: cannot decode FaceStatus TLV" << std::endl;
            break;
          }

        offset += block.size();

        nfd::FaceStatus faceStatus(block);

        ::nfd::FaceUri uri(faceStatus.getRemoteUri());
        if (uri.getScheme() == "udp4") {
          namespace ip = boost::asio::ip;
          boost::system::error_code ec;
          ip::address address = ip::address::from_string(uri.getHost(), ec);

          if (!ec && address.is_multicast()) {
            multicastFaces.push_back(faceStatus.getFaceId());
          }
          else
            continue;
        }
      }

    if (multicastFaces.empty()) {
      discoverHubStage2("No multicast faces available, skipping stage 1");
    }
    else {
      shared_ptr<nfd::Controller> controller = make_shared<nfd::Controller>(ref(m_face));
      shared_ptr<std::pair<size_t, size_t> > nRegistrations =
        make_shared<std::pair<size_t, size_t> >(0, 0);

      nfd::ControlParameters parameters;
      parameters
        .setName("/localhop/ndn-autoconf/hub")
        .setCost(1);

      nRegistrations->first = multicastFaces.size();

      for (std::vector<uint64_t>::iterator i = multicastFaces.begin();
           i != multicastFaces.end(); ++i) {
        parameters.setFaceId(*i);

        controller->start<nfd::RibRegisterCommand>(parameters,
          bind(&NdnAutoconfig::discoverHubStage1_onRegisterSuccess,
               this, controller, nRegistrations),
          bind(&NdnAutoconfig::discoverHubStage1_onRegisterFailure,
               this, _1, _2, controller, nRegistrations));
      }
    }
  }

  void
  discoverHubStage1_onRegisterSuccess(const shared_ptr<nfd::Controller>& controller,
                                      const shared_ptr<std::pair<size_t, size_t> >& nRegistrations)
  {
    nRegistrations->second++;

    if (nRegistrations->first == nRegistrations->second) {
      discoverHubStage1_requestHubData();
    }
  }

  void
  discoverHubStage1_onRegisterFailure(uint32_t code, const std::string& error,
                                      const shared_ptr<nfd::Controller> controller,
                                      const shared_ptr<std::pair<size_t, size_t> >& nRegistrations)
  {
    std::cerr << "ERROR: " << error << " (code: " << code << ")" << std::endl;
    nRegistrations->first--;

    if (nRegistrations->first == nRegistrations->second) {
      if (nRegistrations->first > 0) {
        discoverHubStage1_requestHubData();
      } else {
        discoverHubStage2("Failed to register /localhop/ndn-autoconf/hub for all multicast faces");
      }
    }
  }

  // Start to look for a hub (NDN hub discovery first stage)
  void
  discoverHubStage1_requestHubData()
  {
    Interest interest(Name("/localhop/ndn-autoconf/hub"));
    interest.setInterestLifetime(time::milliseconds(4000)); // 4 seconds
    interest.setMustBeFresh(true);

    std::cerr << "Stage 1: Trying multicast discovery..." << std::endl;
    m_face.expressInterest(interest,
                           bind(&NdnAutoconfig::onDiscoverHubStage1Success, this, _1, _2),
                           bind(&NdnAutoconfig::discoverHubStage2, this, "Timeout"));
  }

  // First stage OnData Callback
  void
  onDiscoverHubStage1Success(const Interest& interest, Data& data)
  {
    const Block& content = data.getContent();
    content.parse();

    // Get Uri
    Block::element_const_iterator blockValue = content.find(tlv::nfd::Uri);
    if (blockValue == content.elements_end())
    {
      discoverHubStage2("Incorrect reply to stage1");
      return;
    }
    std::string faceMgmtUri(reinterpret_cast<const char*>(blockValue->value()),
                            blockValue->value_size());
    connectToHub(faceMgmtUri);
  }

  // First stage OnTimeout callback - start 2nd stage
  void
  discoverHubStage2(const std::string& message)
  {
    std::cerr << message << std::endl;
    std::cerr << "Stage 2: Trying DNS query with default suffix..." << std::endl;

    _res.retry = 2;
    _res.ndots = 10;

    QueryAnswer queryAnswer;

    int answerSize = res_search("_ndn._udp",
                                ns_c_in,
                                ns_t_srv,
                                queryAnswer.buf,
                                sizeof(queryAnswer));

    // 2nd stage failed - move on to the third stage
    if (answerSize < 0)
    {
      discoverHubStage3("Failed to find NDN router using default suffix DNS query");
    }
    else
    {
      bool isParsed = parseHostAndConnectToHub(queryAnswer, answerSize);
      if (isParsed == false)
      {
        // Failed to parse DNS response, try stage 3
        discoverHubStage3("Failed to parse DNS response");
      }
    }
  }

  // Second stage OnTimeout callback
  void
  discoverHubStage3(const std::string& message)
  {
    std::cerr << message << std::endl;
    std::cerr << "Stage 3: Trying to find home router..." << std::endl;

    KeyChain keyChain;
    Name identity = keyChain.getDefaultIdentity();
    std::string serverName = "_ndn._udp.";

    for (Name::const_reverse_iterator i = identity.rbegin(); i != identity.rend(); i++)
    {
      serverName.append(i->toUri());
      serverName.append(".");
    }
    serverName += "_homehub._autoconf.named-data.net";
    std::cerr << "Stage3: About to query for a home router: " << serverName << std::endl;

    QueryAnswer queryAnswer;

    int answerSize = res_query(serverName.c_str(),
                               ns_c_in,
                               ns_t_srv,
                               queryAnswer.buf,
                               sizeof(queryAnswer));


    // 3rd stage failed - abort
    if (answerSize < 0)
    {
      std::cerr << "Failed to find a home router" << std::endl;
      std::cerr << "exit" << std::endl;
    }
    else
    {
      bool isParsed = parseHostAndConnectToHub(queryAnswer, answerSize);
      if (isParsed == false)
      {
        // Failed to parse DNS response
        throw Error("Failed to parse DNS response");
      }
    }

  }

  void
  connectToHub(const std::string& uri)
  {
    std::cerr << "about to connect to: " << uri << std::endl;

    m_controller.start<nfd::FaceCreateCommand>(
      nfd::ControlParameters()
        .setUri(uri),
      bind(&NdnAutoconfig::onHubConnectSuccess, this, _1),
      bind(&NdnAutoconfig::onHubConnectError, this, _1, _2)
    );
  }

  void
  onHubConnectSuccess(const nfd::ControlParameters& resp)
  {
    std::cerr << "Successfully created face: " << resp << std::endl;

    // Register a prefix in RIB
    nfd::ControlParameters ribParameters;
    ribParameters
      .setName("/ndn")
      .setFaceId(resp.getFaceId());

    m_controller.start<nfd::RibRegisterCommand>(
      ribParameters,
      bind(&NdnAutoconfig::onPrefixRegistrationSuccess, this, _1),
      bind(&NdnAutoconfig::onPrefixRegistrationError, this, _1, _2));
  }

  void
  onHubConnectError(uint32_t code, const std::string& error)
  {
    std::ostringstream os;
    os << "Failed to create face: " << error << " (code: " << code << ")";
    throw Error(os.str());
  }


  bool parseHostAndConnectToHub(QueryAnswer& queryAnswer, int answerSize)
  {
    // The references of the next classes are:
    // http://www.diablotin.com/librairie/networking/dnsbind/ch14_02.htm
    // https://gist.github.com/mologie/6027597

    struct rechdr
    {
      uint16_t type;
      uint16_t iclass;
      uint32_t ttl;
      uint16_t length;
    };

    struct srv_t
    {
      uint16_t priority;
      uint16_t weight;
      uint16_t port;
      uint8_t* target;
    };

    if (ntohs(queryAnswer.header.ancount) == 0)
    {
      std::cerr << "No records found\n" << std::endl;
      return false;
    }

    uint8_t* blob = queryAnswer.buf + NS_HFIXEDSZ;

    blob += dn_skipname(blob, queryAnswer.buf + answerSize) + NS_QFIXEDSZ;

    for (int i = 0; i < ntohs(queryAnswer.header.ancount); i++)
    {
      char srvName[NS_MAXDNAME];
      int serverNameSize = dn_expand(queryAnswer.buf,               // message pointer
                                     queryAnswer.buf + answerSize,  // end of message
                                     blob,                          // compressed server name
                                     srvName,                       // expanded server name
                                     NS_MAXDNAME);
      if (serverNameSize < 0)
      {
        return false;
      }

      srv_t* server = reinterpret_cast<srv_t*>(&blob[sizeof(rechdr)]);
      uint16_t convertedPort = be16toh(server->port);

      blob += serverNameSize + NS_HFIXEDSZ + NS_QFIXEDSZ;

      char hostName[NS_MAXDNAME];
      int hostNameSize = dn_expand(queryAnswer.buf,               // message pointer
                                   queryAnswer.buf + answerSize,  // end of message
                                   blob,                          // compressed host name
                                   hostName,                      // expanded host name
                                   NS_MAXDNAME);
      if (hostNameSize < 0)
      {
        return false;
      }

      std::string uri = "udp://";
      uri.append(hostName);
      uri.append(":");
      uri.append(boost::lexical_cast<std::string>(convertedPort));

      connectToHub(uri);
      return true;
    }

    return false;
  }

  void
  onPrefixRegistrationSuccess(const nfd::ControlParameters& commandSuccessResult)
  {
    std::cerr << "Successful in name registration: " << commandSuccessResult << std::endl;
  }

  void
  onPrefixRegistrationError(uint32_t code, const std::string& error)
  {
    std::ostringstream os;
    os << "Failed in name registration, " << error << " (code: " << code << ")";
    throw Error(os.str());
  }

private:
  Face m_face;
  nfd::Controller m_controller;
};

} // namespace tools
} // namespace ndn

int
main(int argc, char** argv)
{
  int opt;
  const char* programName = argv[0];

  while ((opt = getopt(argc, argv, "hV")) != -1) {
    switch (opt) {
    case 'h':
      ndn::tools::usage(programName);
      return 0;
    case 'V':
      std::cout << NFD_VERSION_BUILD_STRING << std::endl;
      return 0;
    }
  }

  try {
    ndn::tools::NdnAutoconfig autoConfigInstance;

    autoConfigInstance.discoverHubStage1();
    autoConfigInstance.run();
  }
  catch (const std::exception& error) {
    std::cerr << "ERROR: " << error.what() << std::endl;
    return 1;
  }
  return 0;
}
