/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2014-2016, Regents of the University of California.
 *
 * This file is part of NDNS (Named Data Networking Domain Name Service).
 * See AUTHORS.md for complete list of NDNS authors and contributors.
 *
 * NDNS 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.
 *
 * NDNS 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
 * NDNS, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "ndns-label.hpp"
#include "logger.hpp"
#include "clients/response.hpp"
#include "clients/query.hpp"
#include "clients/iterative-query-controller.hpp"
#include "validator.hpp"
#include "util/util.hpp"

#include <ndn-cxx/security/key-chain.hpp>
#include <ndn-cxx/face.hpp>
#include <boost/program_options.hpp>
#include <boost/asio.hpp>
#include <boost/filesystem.hpp>
#include <boost/noncopyable.hpp>

#include <memory>
#include <string>

NDNS_LOG_INIT("NdnsDig")

namespace ndn {
namespace ndns {

class NdnsDig
{
public:
  NdnsDig(const Name& hint, const Name& dstLabel,
          const name::Component& rrType, bool shouldValidateIntermediate)
    : m_dstLabel(dstLabel)
    , m_rrType(rrType)
    , m_hint(hint)
    , m_interestLifetime(DEFAULT_INTEREST_LIFETIME)
    , m_validator(m_face)
    , m_shouldValidateIntermediate(shouldValidateIntermediate)
    , m_hasError(false)
  {
    if (m_shouldValidateIntermediate)
      m_ctr = std::unique_ptr<IterativeQueryController>
        (new IterativeQueryController(m_dstLabel, m_rrType, m_interestLifetime,
                                      bind(&NdnsDig::onSucceed, this, _1, _2),
                                      bind(&NdnsDig::onFail, this, _1, _2),
                                      m_face, &m_validator));
    else
      m_ctr = std::unique_ptr<IterativeQueryController>
        (new IterativeQueryController(m_dstLabel, m_rrType, m_interestLifetime,
                                      bind(&NdnsDig::onSucceed, this, _1, _2),
                                      bind(&NdnsDig::onFail, this, _1, _2),
                                      m_face, nullptr));
  }

  void
  run()
  {
    NDNS_LOG_INFO(" =================================== "
                  << "start to dig label = " << this->m_dstLabel
                  << " for type = " << this->m_rrType
                  << " =================================== ");

    try {
      m_ctr->start(); // non-block, may throw exception
      m_face.processEvents();
    }
    catch (std::exception& e) {
      std::cerr << "Error: " << e.what();
      m_hasError = true;
    }
  }

  void
  stop()
  {
    m_face.getIoService().stop();
    NDNS_LOG_TRACE("application stops.");
  }

  void
  setStartZone(const Name& start)
  {
    m_ctr->setStartComponentIndex(start.size());
  }

private:
  void
  onSucceed(const Data& data, const Response& response)
  {
    NDNS_LOG_INFO("Dig get following Response (need verification):");
    Name name = Name().append(response.getZone()).append(response.getRrLabel());
    if (name == m_dstLabel && m_rrType == response.getRrType()) {
      NDNS_LOG_INFO("This is the final response returned by zone=" << response.getZone()
                    << " and NdnsType=" << response.getNdnsType()
                    << ". It contains " << response.getRrs().size() << " RR(s)");

      std::string msg;
      size_t i = 0;
      for (const auto& rr : response.getRrs()) {
        try {
          msg = std::string(reinterpret_cast<const char*>(rr.value()), rr.value_size());
          NDNS_LOG_INFO("succeed to get the info from RR[" << i << "]"
                        "type=" << rr.type() << " content=" << msg);
        }
        catch (std::exception& e) {
          NDNS_LOG_INFO("error to get the info from RR[" << i << "]"
                        "type=" << rr.type());
        }
        ++i;
      }
    }
    else {
      NDNS_LOG_INFO("[* !! *] This is not final response.The target Label: "
                    << m_dstLabel << " may not exist");
    }

    if (m_dstFile.empty()) {
      ;
    }
    else if (m_dstFile == "-") {
      output(data, std::cout, true);
    }
    else {
      NDNS_LOG_INFO("output Data packet to " << m_dstFile << " with BASE64 encoding format");
      std::filebuf fb;
      fb.open(m_dstFile, std::ios::out);
      std::ostream os(&fb);
      output(data, os, false);
    }

    NDNS_LOG_INFO(response);

    NDNS_LOG_TRACE("to verify the response");
    m_validator.validate(data,
                         bind(&NdnsDig::onDataValidated, this, _1),
                         bind(&NdnsDig::onDataValidationFailed, this, _1, _2)
                         );
  }


  void
  onFail(uint32_t errCode, const std::string& errMsg)
  {
    NDNS_LOG_INFO("fail to get response: errCode=" << errCode << " msg=" << errMsg);
    m_hasError = true;
    this->stop();
  }

  void
  onDataValidated(const shared_ptr<const Data>& data)
  {
    NDNS_LOG_INFO("final data pass verification");
    this->stop();
  }

  void
  onDataValidationFailed(const shared_ptr<const Data>& data, const std::string& str)
  {
    NDNS_LOG_INFO("final data does not pass verification");
    m_hasError = true;
    this->stop();
  }

public:
  void
  setInterestLifetime(const time::milliseconds& lifetime)
  {
    m_interestLifetime = lifetime;
  }

  bool
  hasError() const
  {
    return m_hasError;
  }

  void
  setDstFile(const std::string& dstFile)
  {
    m_dstFile = dstFile;
  }

private:
  Name m_dstLabel;
  name::Component m_rrType;

  Name m_hint;
  Name m_certName;
  time::milliseconds m_interestLifetime;

  Face m_face;

  Validator m_validator;
  bool m_shouldValidateIntermediate;
  std::unique_ptr<QueryController> m_ctr;

  bool m_hasError;
  std::string m_dstFile;
};

} // namespace ndns
} // namespace ndn


int
main(int argc, char* argv[])
{
  ndn::ndns::log::init();
  using std::string;
  using namespace ndn;

  Name dstLabel;
  int ttl = 4;
  string rrType = "TXT";
  string dstFile;
  bool shouldValidateIntermediate = true;
  Name start("/ndn");

  try {
    namespace po = boost::program_options;
    po::variables_map vm;

    po::options_description generic("Generic Options");
    generic.add_options()("help,h", "print help message");

    po::options_description config("Configuration");
    config.add_options()
      ("timeout,T", po::value<int>(&ttl), "query timeout. default: 4 sec")
      ("rrtype,t", po::value<std::string>(&rrType), "set request RR Type. default: TXT")
      ("dstFile,d", po::value<std::string>(&dstFile), "set output file of the received Data. "
       "if omitted, not print; if set to be -, print to stdout; else print to file")
      ("start,s", po::value<Name>(&start)->default_value("/ndn"), "set first zone to query")
      ("not-validate,n", "trigger not validate intermediate results")
      ;

    po::options_description hidden("Hidden Options");
    hidden.add_options()
      ("name", po::value<Name>(&dstLabel), "name to be resolved")
      ;
    po::positional_options_description postion;
    postion.add("name", 1);

    po::options_description cmdline_options;
    cmdline_options.add(generic).add(config).add(hidden);

    po::options_description config_file_options;
    config_file_options.add(config).add(hidden);

    po::options_description visible("Usage: ndns-dig /name/to/be/resolved [-t rrType] [-T ttl]"
                                    "[-d dstFile] [-s startZone] [-n]\n"
                                    "Allowed options");

    visible.add(generic).add(config);

    po::parsed_options parsed =
      po::command_line_parser(argc, argv).options(cmdline_options).positional(postion).run();

    po::store(parsed, vm);
    po::notify(vm);

    if (vm.count("help")) {
      std::cout << visible << std::endl;
      return 0;
    }

    if (!vm.count("name")) {
      std::cerr << "must contain a target label parameter." << std::endl;
      std::cerr << visible << std::endl;
      return 1;
    }

    if (!start.isPrefixOf(dstLabel)) {
      std::cerr << "Error: start zone " << start << " is not prefix of the target label "
                << dstLabel << std::endl;
      return 1;
    }

    if (vm.count("not-validate")) {
      shouldValidateIntermediate = false;
    }

    if (ttl < 0) {
      std::cerr << "Error: ttl parameter cannot be negative" << std::endl;
      return 1;
    }
  }
  catch (const std::exception& ex) {
    std::cerr << "Parameter Error: " << ex.what() << std::endl;
    return 1;
  }

  try {
    ndn::ndns::NdnsDig dig("", dstLabel, ndn::name::Component(rrType), shouldValidateIntermediate);
    dig.setInterestLifetime(ndn::time::seconds(ttl));
    dig.setDstFile(dstFile);

    // Due to ndn testbed does not contain the root zone
    // dig here starts from the TLD (Top-level Domain)
    // precondition is that TLD : 1) only contains one component in its name; 2) its name is routable
    dig.setStartZone(start);

    dig.run();

    if (dig.hasError())
      return 1;
    else
      return 0;
  }
  catch (const ndn::ValidatorConfig::Error& e) {
    std::cerr << "Fail to create the validator: " << e.what() << std::endl;
    return 1;
  }
  catch (const std::exception& e) {
    std::cerr << "Error: " << e.what() << std::endl;
    return 1;
  }

}
