/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2017-2020, Regents of the University of California.
 *
 * This file is part of ndncert, a certificate management system based on NDN.
 *
 * ndncert 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.
 *
 * ndncert 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 copies of the GNU General Public License along with
 * ndncert, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
 *
 * See AUTHORS.md for complete list of ndncert authors and contributors.
 */

#include "requester.hpp"
#include <ndn-cxx/security/verification-helpers.hpp>
#include <boost/asio.hpp>
#include <boost/program_options/options_description.hpp>
#include <boost/program_options/parsers.hpp>
#include <boost/program_options/variables_map.hpp>
#include <iostream>
#include <string>

namespace ndn {
namespace ndncert {
namespace requester {

static void
selectCaProfile(std::string configFilePath);
static void
runProbe(CaProfile profile);
static void
runNew(CaProfile profile, Name identityName);
static void
runChallenge(const std::string& challengeType);

size_t nStep = 1;
Face face;
security::KeyChain keyChain;
shared_ptr<RequestState> requesterState = nullptr;

static void
captureParams(std::multimap<std::string, std::string>& requirement)
{
  std::list<std::string> results;
  for (auto& item : requirement) {
    std::cerr << std::get<1>(item) << std::endl;
    std::string captured;
    getline(std::cin, captured);
    std::get<1>(item) = captured;
  }
  std::cerr << "Got it. This is what you've provided:" << std::endl;
  for (const auto& item : requirement) {
    std::cerr << std::get<0>(item) << " : " << std::get<1>(item) << std::endl;
  }
}

static std::multimap<std::string, std::string>
captureParams(const std::vector<std::string>& requirement)
{
  std::multimap<std::string, std::string> results;
  for (const auto& r : requirement) {
    results.emplace(r, "Please input: " + r);
  }
  captureParams(results);
  return results;
}

static int
captureValidityPeriod()
{
  std::cerr << "\n***************************************\n"
            << "Step " << nStep++
            << ": Please type in your expected validity period of your certificate."
            << " Type the number of hours (168 for week, 730 for month, 8760 for year)."
            << " The CA may reject your application if your expected period is too long." << std::endl;
  while (true) {
    std::string periodStr = "";
    getline(std::cin, periodStr);
    try {
      return std::stoul(periodStr);
    }
    catch (const std::exception& e) {
      std::cerr << "Your input is invalid. Try again: " << std::endl;
    }
  }
}

static void
onNackCb()
{
  std::cerr << "Got NACK\n";
}

static void
timeoutCb()
{
  std::cerr << "Interest sent time out\n";
}

static void
certFetchCb(const Data& reply)
{
  auto item = Requester::onCertFetchResponse(reply);
  if (item) {
    keyChain.addCertificate(keyChain.getPib().getIdentity(item->getIdentity()).getKey(item->getKeyName()), *item);
  }
  std::cerr << "\n***************************************\n"
            << "Step " << nStep++
            << ": DONE\nCertificate with Name: " << reply.getName().toUri()
            << "has already been installed to your local keychain" << std::endl
            << "Exit now";
  face.getIoService().stop();
}

static void
challengeCb(const Data& reply)
{
  try {
    Requester::onChallengeResponse(*requesterState, reply);
  }
  catch (const std::exception& e) {
    std::cerr << "Error when decoding challenge step: " << e.what() << std::endl;
    exit(1);
  }
  if (requesterState->status == Status::SUCCESS) {
    std::cerr << "Certificate has already been issued, downloading certificate..." << std::endl;
    face.expressInterest(*Requester::genCertFetchInterest(*requesterState), bind(&certFetchCb, _2),
                         bind(&onNackCb), bind(&timeoutCb));
    return;
  }
  runChallenge(requesterState->challengeType);
}

static void
newCb(const Data& reply)
{
  std::list<std::string> challengeList;
  try {
    challengeList = Requester::onNewRenewRevokeResponse(*requesterState, reply);
  }
  catch (const std::exception& e) {
    std::cerr << "Error on decoding NEW step reply because: " << e.what() << std::endl;
    exit(1);
  }

  size_t challengeIndex = 0;
  if (challengeList.size() < 1) {
    std::cerr << "There is no available challenge provided by the CA. Exit" << std::endl;
    exit(1);
  }
  else if (challengeList.size() > 1) {
    std::cerr << "\n***************************************\n"
              << "Step " << nStep++
              << ": CHALLENGE SELECTION" << std::endl;
    size_t count = 0;
    std::string choice = "";
    for (auto item : challengeList) {
      std::cerr << "> Index: " << count++ << std::endl
                << ">> Challenge:" << item << std::endl;
    }
    std::cerr << "Please type in the challenge index that you want to perform:" << std::endl;
    while (true) {
      getline(std::cin, choice);
      try {
        challengeIndex = std::stoul(choice);
      }
      catch (const std::exception& e) {
        std::cerr << "Your input is not valid. Try again:" << std::endl;
        continue;
      }
      if (challengeIndex >= count) {
        std::cerr << "Your input index is out of range. Try again:" << std::endl;
        continue;
      }
      break;
    }
  }
  auto it = challengeList.begin();
  std::advance(it, challengeIndex);
  std::cerr << "The challenge has been selected: " << *it << std::endl;
  runChallenge(*it);
}

static void
InfoCb(const Data& reply, const Name& certFullName)
{
  optional<CaProfile> profile;
  try {
    if (certFullName.empty()) {
      profile = Requester::onCaProfileResponse(reply);
    }
    else {
      profile = Requester::onCaProfileResponseAfterRedirection(reply, certFullName);
    }
  }
  catch (const std::exception& e) {
    std::cerr << "The fetched CA information cannot be used because: " << e.what() << std::endl;
    return;
  }
  std::cerr << "\n***************************************\n"
            << "Step " << nStep++
            << ": Will use a new trust anchor, please double check the identity info:" << std::endl
            << "> New CA name: " << profile->caPrefix.toUri() << std::endl
            << "> This trust anchor information is signed by: " << reply.getSignatureInfo().getKeyLocator() << std::endl
            << "> The certificate: " << profile->cert << std::endl
            << "Do you trust the information? Type in YES or NO" << std::endl;

  std::string answer;
  getline(std::cin, answer);
  boost::algorithm::to_lower(answer);
  if (answer == "yes") {
    std::cerr << "You answered YES: new CA " << profile->caPrefix.toUri() << " will be used" << std::endl;
    runProbe(*profile);
    // client.getClientConf().save(std::string(SYSCONFDIR) + "/ndncert/client.conf");
  }
  else {
    std::cerr << "You answered NO: new CA " << profile->caPrefix.toUri() << " will not be used" << std::endl;
    exit(0);
  }
}

static void
probeCb(const Data& reply, CaProfile profile)
{
  std::vector<std::pair<Name, int>> names;
  std::vector<Name> redirects;
  Requester::onProbeResponse(reply, profile, names, redirects);
  size_t count = 0;
  std::cerr << "\n***************************************\n"
            << "Step " << nStep++
            << ": You can either select one of the following names suggested by the CA: " << std::endl;
  for (const auto& name : names) {
    std::cerr << "> Index: " << count++ << std::endl
              << ">> Suggested name: " << name.first.toUri() << std::endl
              << ">> Corresponding Max sufiix length: " << name.second << std::endl;
  }
  std::cerr << "\nOr choose another trusted CA suggested by the CA: " << std::endl;
  for (const auto& redirect : redirects) {
    std::cerr << "> Index: " << count++ << std::endl
              << ">> Suggested CA: " << security::extractIdentityFromCertName(redirect.getPrefix(-1)) << std::endl;
  }
  std::cerr << "Please type in the index of your choice:" << std::endl;
  size_t index = 0;
  try {
    std::string input;
    getline(std::cin, input);
    index = std::stoul(input);
  }
  catch (const std::exception& e) {
    std::cerr << "Your input is Invalid. Exit" << std::endl;
    exit(0);
  }
  if (index >= names.size() + redirects.size()) {
    std::cerr << "Your input is not an existing index. Exit" << std::endl;
    return;
  }
  if (index < names.size()) {
    //names
    std::cerr << "You selected name: " << names[index].first.toUri() << std::endl;
    //TODO add prompt to "add suffix"
    runNew(profile, names[index].first);
  }
  else {
    //redirects
    auto redirectedCaFullName = redirects[index - names.size()];
    auto redirectedCaName = security::extractIdentityFromCertName(redirectedCaFullName.getPrefix(-1));
    std::cerr << "You selected to be redirected to CA: " << redirectedCaName.toUri() << std::endl;
    face.expressInterest(
        *Requester::genCaProfileDiscoveryInterest(redirectedCaName),
        [&](const Interest&, const Data& data) {
          auto fetchingInterest = Requester::genCaProfileInterestFromDiscoveryResponse(data);
          face.expressInterest(*fetchingInterest,
                               bind(&InfoCb, _2, redirectedCaFullName),
                               bind(&onNackCb),
                               bind(&timeoutCb));
        },
        bind(&onNackCb),
        bind(&timeoutCb));
  }
}

static void
selectCaProfile(std::string configFilePath)
{
  ProfileStorage profileStorage;
  try {
    profileStorage.load(configFilePath);
  }
  catch (const std::exception& e) {
    std::cerr << "Cannot load the configuration file: " << e.what() << std::endl;
    exit(1);
  }
  size_t count = 0;
  std::cerr << "***************************************\n"
            << "Step " << nStep++ << ": CA SELECTION" << std::endl;
  for (auto item : profileStorage.getKnownProfiles()) {
    std::cerr << "> Index: " << count++ << std::endl
              << ">> CA prefix:" << item.caPrefix << std::endl
              << ">> Introduction: " << item.caInfo << std::endl;
  }
  std::cerr << "Please type in the CA's index that you want to apply or type in NONE if your expected CA is not in the list:\n";

  std::string caIndexS, caIndexSLower;
  getline(std::cin, caIndexS);
  caIndexSLower = caIndexS;
  boost::algorithm::to_lower(caIndexSLower);
  if (caIndexSLower == "none") {
    std::cerr << "\n***************************************\n"
              << "Step " << nStep << ": ADD NEW CA\nPlease type in the CA's Name:" << std::endl;
    std::string expectedCAName;
    getline(std::cin, expectedCAName);
    face.expressInterest(
        *Requester::genCaProfileDiscoveryInterest(Name(expectedCAName)),
        [&](const Interest&, const Data& data) {
          auto fetchingInterest = Requester::genCaProfileInterestFromDiscoveryResponse(data);
          face.expressInterest(*fetchingInterest,
                               bind(&InfoCb, _2, Name()),
                               bind(&onNackCb),
                               bind(&timeoutCb));
        },
        bind(&onNackCb),
        bind(&timeoutCb));
  }
  else {
    size_t caIndex;
    try {
      caIndex = std::stoul(caIndexS);
    }
    catch (const std::exception& e) {
      std::cerr << "Your input is neither NONE nor a valid index. Exit" << std::endl;
      return;
    }
    if (caIndex >= count) {
      std::cerr << "Your input is not an existing index. Exit" << std::endl;
      return;
    }
    auto itemIterator = profileStorage.getKnownProfiles().cbegin();
    std::advance(itemIterator, caIndex);
    auto targetCaItem = *itemIterator;
    runProbe(targetCaItem);
  }
}

static void
runProbe(CaProfile profile)
{
  std::cerr << "\n***************************************\n"
            << "Step " << nStep++
            << ": Do you know your identity name to be certified by CA "
            << profile.caPrefix.toUri()
            << " already? Type in YES or NO" << std::endl;
  bool validAnswer = false;
  while (!validAnswer) {
    std::string answer;
    getline(std::cin, answer);
    boost::algorithm::to_lower(answer);
    if (answer == "yes") {
      validAnswer = true;
      std::cerr << "You answered YES" << std::endl;
      std::cerr << "\n***************************************\n"
                << "Step " << nStep++
                << ": Please type in the full identity name you want to get (with CA prefix "
                << profile.caPrefix.toUri()
                << "):" << std::endl;
      std::string identityNameStr;
      getline(std::cin, identityNameStr);
      runNew(profile, Name(identityNameStr));
    }
    else if (answer == "no") {
      validAnswer = true;
      std::cerr << "You answered NO" << std::endl;
      std::cerr << "\n***************************************\n"
                << "Step " << nStep++ << ": Please provide information for name assignment" << std::endl;
      auto capturedParams = captureParams(profile.probeParameterKeys);
      face.expressInterest(*Requester::genProbeInterest(profile, std::move(capturedParams)),
                           bind(&probeCb, _2, profile), bind(&onNackCb), bind(&timeoutCb));
    }
    else {
      std::cerr << "Invalid answer. Type in YES or NO" << std::endl;
    }
  }
}

static void
runNew(CaProfile profile, Name identityName)
{
  int validityPeriod = captureValidityPeriod();
  auto now = time::system_clock::now();
  std::cerr << "The validity period of your certificate will be: " << validityPeriod << " hours" << std::endl;
  requesterState =std::make_shared<RequestState>(keyChain, profile, RequestType::NEW);
  auto interest = Requester::genNewInterest(*requesterState, identityName, now, now + time::hours(validityPeriod));
  if (interest != nullptr) {
    face.expressInterest(*interest, bind(&newCb, _2), bind(&onNackCb), bind(&timeoutCb));
  }
  else {
    std::cerr << "Cannot generate the Interest for NEW step. Exit" << std::endl;
  }
}

static void
runChallenge(const std::string& challengeType)
{
  std::multimap<std::string, std::string> requirement;
  try {
    requirement = Requester::selectOrContinueChallenge(*requesterState, challengeType);
  }
  catch (const std::exception& e) {
    std::cerr << "Error. Cannot successfully load the Challenge Module with error: " << std::string(e.what())
              << "Exit." << std::endl;
    exit(1);
  }
  if (requirement.size() > 0) {
    std::cerr << "\n***************************************\n"
              << "Step " << nStep
              << ": Please provide parameters used for Identity Verification Challenge" << std::endl;
    captureParams(requirement);
  }
  face.expressInterest(*Requester::genChallengeInterest(*requesterState, std::move(requirement)),
                       bind(&challengeCb, _2), bind(&onNackCb), bind(&timeoutCb));
}

static void
handleSignal(const boost::system::error_code& error, int signalNum)
{
  if (error) {
    return;
  }
  const char* signalName = ::strsignal(signalNum);
  std::cerr << "Exiting on signal ";
  if (signalName == nullptr) {
    std::cerr << signalNum;
  }
  else {
    std::cerr << signalName;
  }
  std::cerr << std::endl;
  if (requesterState) {
    Requester::endSession(*requesterState);
  }
  face.getIoService().stop();
  exit(1);
}

int
main(int argc, char* argv[])
{
  boost::asio::signal_set terminateSignals(face.getIoService());
  terminateSignals.add(SIGINT);
  terminateSignals.add(SIGTERM);
  terminateSignals.async_wait(handleSignal);

  namespace po = boost::program_options;
  std::string configFilePath = std::string(NDNCERT_SYSCONFDIR) + "/ndncert/client.conf";
  po::options_description description("General Usage\n ndncert-client [-h] [-c] [-v]\n");
  description.add_options()("help,h", "produce help message")("config-file,c", po::value<std::string>(&configFilePath), "configuration file name");
  po::positional_options_description p;

  po::variables_map vm;
  try {
    po::store(po::command_line_parser(argc, argv).options(description).positional(p).run(), vm);
    po::notify(vm);
  }
  catch (const std::exception& e) {
    std::cerr << "ERROR: " << e.what() << std::endl;
    return 1;
  }
  if (vm.count("help") != 0) {
    std::cerr << description << std::endl;
    return 0;
  }
  selectCaProfile(configFilePath);
  face.processEvents();
  return 0;
}

} // namespace requester
} // namespace ndncert
} // namespace ndn

int
main(int argc, char* argv[])
{
  return ndn::ndncert::requester::main(argc, argv);
}
