/* -*- 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-email.hpp"
#include "../ca-module.hpp"
#include "../logging.hpp"
#include <regex>

namespace ndn {
namespace ndncert {

_LOG_INIT(ndncert.ChallengeEmail);

NDNCERT_REGISTER_CHALLENGE(ChallengeEmail, "email");

const std::string ChallengeEmail::NEED_CODE = "need-code";
const std::string ChallengeEmail::WRONG_CODE = "wrong-code";
const std::string ChallengeEmail::FAILURE_INVALID_EMAIL = "failure-invalid-email";
const std::string ChallengeEmail::JSON_EMAIL = "email";
const std::string ChallengeEmail::JSON_CODE = "code";

ChallengeEmail::ChallengeEmail(const std::string& scriptPath,
                               const size_t& maxAttemptTimes,
                               const time::seconds secretLifetime)
  : ChallengeModule("email")
  , m_sendEmailScript(scriptPath)
  , m_maxAttemptTimes(maxAttemptTimes)
  , m_secretLifetime(secretLifetime)
{
}

// For CA
void
ChallengeEmail::handleChallengeRequest(const Block& params, CertificateRequest& request)
{
  params.parse();
  auto currentTime = time::system_clock::now();
  if (request.m_challengeStatus == "") {
    // for the first time, init the challenge
    std::string emailAddress = readString(params.get(tlv_parameter_value));
    if (!isValidEmailAddress(emailAddress)) {
      request.m_status = Status::FAILURE;
      request.m_challengeStatus = FAILURE_INVALID_EMAIL;
      return;
    }
    // check whether this email is the same as the one used in PROBE
    if (request.m_probeToken != nullptr) {
      const auto& content = request.m_probeToken->getContent();
      const auto& json = CaModule::jsonFromBlock(content);
      const auto& expectedEmail = json.get("email", "");
      Name expectedPrefix(json.get(JSON_CA_NAME, ""));
      if (expectedEmail != emailAddress || !expectedPrefix.isPrefixOf(request.m_cert.getName())) {
        _LOG_ERROR("Cannot match with the PROBE token. Input email: " << emailAddress
                   << " Email in Token: " << expectedEmail
                   << " Requested Cert Name: " << request.m_cert.getName()
                   << " Identity Name got from Token: " << expectedPrefix);
        return;
      }
    }
    request.m_status = Status::CHALLENGE;
    request.m_challengeStatus = NEED_CODE;
    request.m_challengeType = CHALLENGE_TYPE;
    std::string emailCode = generateSecretCode();
    JsonSection secretJson;
    secretJson.add(JSON_CODE, emailCode);
    request.m_challengeSecrets = secretJson;
    request.m_challengeTp = time::toIsoString(currentTime);
    request.m_remainingTime = m_secretLifetime.count();
    request.m_remainingTries = m_maxAttemptTimes;
    // send out the email
    sendEmail(emailAddress, emailCode, request);
    _LOG_TRACE("Secret for request " << request.m_requestId << " : " << emailCode);
    return;
  }
  else 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));
    const auto realCode = request.m_challengeSecrets.get<std::string>(JSON_CODE);
    if (currentTime - time::fromIsoString(request.m_challengeTp) >= m_secretLifetime) {
      // secret expires
      request.m_status = Status::FAILURE;
      request.m_challengeStatus = CHALLENGE_STATUS_FAILURE_TIMEOUT;
      updateRequestOnChallengeEnd(request);
      _LOG_TRACE("Secret expired. Challenge failed.");
      return;
    }
    else if (givenCode == realCode) {
      // the code is correct
      request.m_status = Status::PENDING;
      request.m_challengeStatus = CHALLENGE_STATUS_SUCCESS;
      updateRequestOnChallengeEnd(request);
      _LOG_TRACE("Secret code matched. Challenge succeeded.");
      return;
    }
    else {
      // check rest attempt times
      if (request.m_remainingTries > 1) {
        request.m_challengeStatus = WRONG_CODE;
        request.m_remainingTries = request.m_remainingTries - 1;
        auto remainTime = m_secretLifetime - (currentTime - time::fromIsoString(request.m_challengeTp));
        request.m_remainingTime = remainTime.count();
        _LOG_TRACE("Secret code didn't match. Remaining Tries - 1.");
        return;
      }
      else {
        // run out times
        request.m_status = Status::FAILURE;
        request.m_challengeStatus = CHALLENGE_STATUS_FAILURE_MAXRETRY;
        updateRequestOnChallengeEnd(request);
        _LOG_TRACE("Secret code didn't match. Ran out tires. Challenge failed.");
        return;
      }
    }
  }
  else {
    _LOG_ERROR("The challenge status is wrong");
    request.m_status = Status::FAILURE;
    return;
  }
}

// For Client
JsonSection
ChallengeEmail::getRequirementForChallenge(Status status, const std::string& challengeStatus)
{
  JsonSection result;
  if (status == Status::BEFORE_CHALLENGE && challengeStatus == "") {
    result.put(JSON_EMAIL, "Please_input_your_email_address");
  }
  else if (status == Status::CHALLENGE && challengeStatus == NEED_CODE) {
    result.put(JSON_CODE, "Please_input_your_verification_code");
  }
  else if (status == Status::CHALLENGE && challengeStatus == WRONG_CODE) {
    result.put(JSON_CODE, "Incorrect_code_please_try_again");
  }
  else {
    _LOG_ERROR("CA's status and challenge status are wrong");
  }
  return result;
}

JsonSection
ChallengeEmail::genChallengeRequestJson(Status status, const std::string& challengeStatus, const JsonSection& params)
{
  JsonSection result;
  if (status == Status::BEFORE_CHALLENGE && challengeStatus == "") {
    result.put(JSON_CLIENT_SELECTED_CHALLENGE, CHALLENGE_TYPE);
    result.put(JSON_EMAIL, params.get(JSON_EMAIL, ""));
  }
  else if (status == Status::CHALLENGE && challengeStatus == NEED_CODE) {
    result.put(JSON_CLIENT_SELECTED_CHALLENGE, CHALLENGE_TYPE);
    result.put(JSON_CODE, params.get(JSON_CODE, ""));
  }
  else if (status == Status::CHALLENGE && challengeStatus == WRONG_CODE) {
    result.put(JSON_CLIENT_SELECTED_CHALLENGE, CHALLENGE_TYPE);
    result.put(JSON_CODE, params.get(JSON_CODE, ""));
  }
  else {
    _LOG_ERROR("Client's status and challenge status are wrong");
  }
  return result;
}

Block
ChallengeEmail::genChallengeRequestTLV(Status status, const std::string& challengeStatus, const JsonSection& params)
{
  Block request = makeEmptyBlock(tlv_encrypted_payload);
  if (status == Status::BEFORE_CHALLENGE && challengeStatus == "") {
    request.push_back(makeStringBlock(tlv_selected_challenge, CHALLENGE_TYPE));
    request.push_back(makeStringBlock(tlv_parameter_key, JSON_EMAIL));
    request.push_back(makeStringBlock(tlv_parameter_value, params.get(JSON_EMAIL,"")));
  }
  else if (status == Status::CHALLENGE && challengeStatus == NEED_CODE) {
    request.push_back(makeStringBlock(tlv_selected_challenge, CHALLENGE_TYPE));
    request.push_back(makeStringBlock(tlv_parameter_key, JSON_CODE));
    request.push_back(makeStringBlock(tlv_parameter_value, params.get(JSON_CODE,"")));
  }
  else if (status == Status::CHALLENGE && challengeStatus == WRONG_CODE) {
    request.push_back(makeStringBlock(tlv_selected_challenge, CHALLENGE_TYPE));
    request.push_back(makeStringBlock(tlv_parameter_key, JSON_CODE));
    request.push_back(makeStringBlock(tlv_parameter_value, params.get(JSON_CODE,"")));
  }
  else {
    _LOG_ERROR("Client's status and challenge status are wrong");
  }
  request.encode();
  return request;
}

bool
ChallengeEmail::isValidEmailAddress(const std::string& emailAddress)
{
  const std::string pattern = R"_REGEX_((^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+.[a-zA-Z0-9\-\.]+$))_REGEX_";
  static const std::regex emailPattern(pattern);
  return std::regex_match(emailAddress, emailPattern);
}

void
ChallengeEmail::sendEmail(const std::string& emailAddress, const std::string& secret,
                          const CertificateRequest& request) const
{
  std::string command = m_sendEmailScript;
  command += " \"" + emailAddress + "\" \"" + secret + "\" \""
    + request.m_caPrefix.toUri() + "\" \"" + request.m_cert.getName().toUri()  + "\"";
  int result = system(command.c_str());
  if (result == -1) {
    _LOG_TRACE("EmailSending Script " + m_sendEmailScript + " fails.");
  }
  _LOG_TRACE("EmailSending Script " + m_sendEmailScript +
             " was executed successfully with return value" + std::to_string(result) + ".");
  return;
}

} // namespace ndncert
} // namespace ndn
