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

#include <ndn-cxx/util/random.hpp>

#include "logging.hpp"

namespace ndn {
namespace ndncert {

_LOG_INIT(ndncert.challenge.pin);
NDNCERT_REGISTER_CHALLENGE(ChallengePin, "pin");

const std::string ChallengePin::NEED_CODE = "need-code";
const std::string ChallengePin::WRONG_CODE = "wrong-code";
const std::string ChallengePin::PARAMETER_KEY_CODE = "pin-code";

ChallengePin::ChallengePin(const size_t& maxAttemptTimes, const time::seconds& secretLifetime)
    : ChallengeModule("pin")
    , m_secretLifetime(secretLifetime)
    , m_maxAttemptTimes(maxAttemptTimes)
{
}

// For CA
std::tuple<ErrorCode, std::string>
ChallengePin::handleChallengeRequest(const Block& params, CertificateRequest& request)
{
  params.parse();
  auto currentTime = time::system_clock::now();
  if (request.m_status == Status::BEFORE_CHALLENGE) {
    _LOG_TRACE("Challenge Interest arrives. Init the challenge");
    // for the first time, init the challenge
    std::string secretCode = generateSecretCode();
    JsonSection secretJson;
    secretJson.add(PARAMETER_KEY_CODE, secretCode);
    _LOG_TRACE("Secret for request " << request.m_requestId << " : " << secretCode);
    return returnWithNewChallengeStatus(request, NEED_CODE, std::move(secretJson), m_maxAttemptTimes, m_secretLifetime.count());
  }

  if (request.m_challengeStatus == NEED_CODE || request.m_challengeStatus == WRONG_CODE) {
    _LOG_TRACE("Challenge Interest arrives. Challenge Status: " << request.m_challengeStatus);
    // the incoming interest should bring the pin code
    std::string givenCode = readString(params.get(tlv_parameter_value));
    auto secret = request.m_challengeSecrets;
    if (currentTime - time::fromIsoString(request.m_challengeTp) >= m_secretLifetime) {
      return returnWithError(request, ErrorCode::OUT_OF_TIME, "Secret expired.");
    }
    if (givenCode == secret.get<std::string>(PARAMETER_KEY_CODE)) {
      _LOG_TRACE("Correct PIN code. Challenge succeeded.");
      return returnWithSuccess(request);
    }
    // check rest attempt times
    if (request.m_remainingTries > 1) {
      auto remainTime = m_secretLifetime - (currentTime - time::fromIsoString(request.m_challengeTp));
      _LOG_TRACE("Wrong PIN code provided. Remaining Tries - 1.");
      return returnWithNewChallengeStatus(request, WRONG_CODE, std::move(secret), request.m_remainingTries - 1, remainTime.count());
    }
    else {
      // run out times
      _LOG_TRACE("Wrong PIN code provided. Ran out tires. Challenge failed.");
      return returnWithError(request, ErrorCode::OUT_OF_TRIES, "Ran out tires.");
    }
  }
  return returnWithError(request, ErrorCode::INVALID_PARAMETER, "Unexpected status or challenge status");
}

// For Client
std::vector<std::tuple<std::string, std::string>>
ChallengePin::getRequestedParameterList(Status status, const std::string& challengeStatus)
{
  std::vector<std::tuple<std::string, std::string>> result;
  if (status == Status::BEFORE_CHALLENGE) {
    // do nothing
  }
  else if (status == Status::CHALLENGE && challengeStatus == NEED_CODE) {
    result.push_back(std::make_tuple(PARAMETER_KEY_CODE, "Please input your PIN code"));
  }
  else if (status == Status::CHALLENGE && challengeStatus == WRONG_CODE) {
    result.push_back(std::make_tuple(PARAMETER_KEY_CODE, "Incorrect PIN code, please try again"));
  }
  else {
    BOOST_THROW_EXCEPTION(std::runtime_error("Unexpected status or challenge status."));
  }
  return result;
}

Block
ChallengePin::genChallengeRequestTLV(Status status, const std::string& challengeStatus, std::vector<std::tuple<std::string, std::string>>&& params)
{
  Block request = makeEmptyBlock(tlv_encrypted_payload);
  if (status == Status::BEFORE_CHALLENGE) {
    request.push_back(makeStringBlock(tlv_selected_challenge, CHALLENGE_TYPE));
  }
  else if (status == Status::CHALLENGE && (challengeStatus == NEED_CODE || challengeStatus == WRONG_CODE)) {
    if (params.size() != 1 || std::get<0>(params[0]) != PARAMETER_KEY_CODE) {
      BOOST_THROW_EXCEPTION(std::runtime_error("Wrong parameter provided."));
    }
    request.push_back(makeStringBlock(tlv_selected_challenge, CHALLENGE_TYPE));
    request.push_back(makeStringBlock(tlv_parameter_key, PARAMETER_KEY_CODE));
    request.push_back(makeStringBlock(tlv_parameter_value, std::get<1>(params[0])));
  }
  else {
    BOOST_THROW_EXCEPTION(std::runtime_error("Unexpected status or challenge status."));
  }
  request.encode();
  return request;
}
}  // namespace ndncert
}  // namespace ndn
