/* -*- 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.
 */

#ifndef NDNCERT_REQUESTER_HPP
#define NDNCERT_REQUESTER_HPP

#include "configuration.hpp"
#include "ca-state.hpp"
#include "crypto-support/crypto-helper.hpp"

namespace ndn {
namespace ndncert {

// TODO
// For each RequesterState, create a validator instance and initialize it with CA's cert
// The validator instance should be in CaProfile

struct RequesterState {
  explicit
  RequesterState(security::KeyChain& keyChain, const CaProfile& caItem, RequestType requestType);

  /**
   * The CA profile for this request.
   */
  CaProfile m_caItem;
  /**
   * The local keychain to generate and install identities, keys and certificates
   */
  security::KeyChain& m_keyChain;
  /**
   * The type of request. Either NEW, RENEW, or REVOKE.
   */
  RequestType m_type;

  /**
   * The identity name for the requesting certificate.
   */
  Name m_identityName;
  /**
   * The keypair for the request.
   */
  security::Key m_keyPair;
  /**
   * The CA-generated request ID for the request.
   */
  std::string m_requestId;
  /**
   * The current status of the request.
   */
  Status m_status = Status::NOT_STARTED;

  /**
   * The type of challenge chosen.
   */
  std::string m_challengeType;
  /**
   * The status of the current challenge.
   */
  std::string m_challengeStatus;
  /**
   * The remaining number of tries left for the challenge
   */
  int m_remainingTries = 0;
  /**
   * The time this challenge will remain fresh
   */
  time::system_clock::TimePoint m_freshBefore;
  /**
   * the name of the certificate being issued.
   */
  Name m_issuedCertName;

  ECDHState m_ecdh;
  uint8_t m_aesKey[16] = {0};

  bool m_isCertInstalled = false;
  bool m_isNewlyCreatedIdentity = false;
  bool m_isNewlyCreatedKey = false;
};

class Requester : noncopyable
{
public:
  /**
   * Generates a CA profile discovery Interest following RDR protocol.
   * @param caName, the name prefix of the CA.
   * @return A shared pointer to an Interest ready to be sent.
   */
  static shared_ptr<Interest>
  genCaProfileDiscoveryInterest(const Name& caName);

  /**
   * Generates a CA profile fetching Interest following RDR protocol.
   * @param reply, the Data packet replied from discovery Interest.
   * @return A shared pointer to an Interest ready to be sent.
   */
  static shared_ptr<Interest>
  genCaProfileInterestFromDiscoveryResponse(const Data& reply);

  /**
   * Decodes the CA profile from the replied CA profile Data packet.
   * Will first verify the signature of the packet using the key provided inside the profile.
   * The application should be cautious whether to add CaProfile into the RequesterCaCache.
   * @param reply, the Data packet replied from CA profile fetching Interest.
   * @return the CaProfile if decoding is successful
   * @throw std::runtime_error if the decoding fails or receiving an error packet.
   */
  static boost::optional<CaProfile>
  onCaProfileResponse(const Data& reply);

  /**
   * Decodes the CA profile from the replied CA profile Data packet after the redirection.
   * Will first verify the signature of the packet using the key provided inside the profile and
   * verify the certificate's digest matches the one obtained from the original CA.
   * The application should be cautious whether to add CaProfile into the RequesterCaCache.
   * @param reply, the Data packet replied from CA profile fetching Interest.
   * @param caCertFullName, the full name obtained from original CA's probe response.
   * @return the CaProfile if decoding is successful
   * @throw std::runtime_error if the decoding fails or receiving an error packet.
   */
  static boost::optional<CaProfile>
  onCaProfileResponseAfterRedirection(const Data& reply, const Name& caCertFullName);

  /**
   * Generates a PROBE interest to the CA (for suggested name assignments).
   * @param ca, the CA that interest is send to
   * @param probeInfo, the requester information to carry to the CA
   * @return A shared pointer of to the encoded interest, ready to be sent.
   */
  static shared_ptr<Interest>
  genProbeInterest(const CaProfile& ca, std::vector<std::tuple<std::string, std::string>>&& probeInfo);

  /**
   * Decodes the replied data for PROBE process from the CA.
   * Will first verify the signature of the packet using the key provided inside the profile.
   * @param reply, The replied data packet
   * @param ca, the profile of the CA that replies the packet
   * @param identityNames, The vector to load the decoded identity names from the data.
   * @param otherCas, The vector to load the decoded redirection CA prefixes from the data.
   * @throw std::runtime_error if the decoding fails or receiving an error packet.
   */
  static void
  onProbeResponse(const Data& reply, const CaProfile& ca,
                  std::vector<Name>& identityNames, std::vector<Name>& otherCas);

  // NEW/REVOKE/RENEW related helpers
  /**
   * Generates a NEW interest to the CA.
   * @param state, The current requester state for this request. Will be modified in the function.
   * @param identityName, The identity name to be requested.
   * @param notBefore, The expected notBefore field for the certificate (starting time)
   * @param notAfter, The expected notAfter field for the certificate (expiration time)
   * @return The shared pointer to the encoded interest.
   */
  static shared_ptr<Interest>
  genNewInterest(RequesterState& state, const Name& identityName,
                      const time::system_clock::TimePoint& notBefore,
                      const time::system_clock::TimePoint& notAfter);

  /**
   * Generates a REVOKE interest to the CA.
   * @param state, The current requester state for this request. Will be modified in the function.
   * @param certificate, the certificate to the revoked.
   * @return The shared pointer to the encoded interest.
   */
  static shared_ptr<Interest>
  genRevokeInterest(RequesterState& state, const security::Certificate& certificate);

  /**
   * Decodes the replied data of NEW, RENEW, or REVOKE interest from the CA.
   * @param state, the current requester state for the request. Will be updated in the function.
   * @param reply, the replied data from the network
   * @return the list of challenge accepted by the CA, for CHALLENGE step.
   * @throw std::runtime_error if the decoding fails or receiving an error packet.
   */
  static std::list<std::string>
  onNewRenewRevokeResponse(RequesterState& state, const Data& reply);

  // CHALLENGE helpers
  /**
   * Generates the required parameter for the selected challenge for the request
   * @param state, The requester state of the request.Will be updated in the function.
   * @param challengeSelected, The selected challenge for the request.
   *            Can use state.m_challengeType to continue.
   * @return The requirement list for the current stage of the challenge, in name, prompt mapping.
   */
  static std::vector<std::tuple<std::string, std::string>>
  selectOrContinueChallenge(RequesterState& state, const std::string& challengeSelected);

  /**
   * Generates the CHALLENGE interest for the request.
   * @param state, The requester state of the request.
   * @param parameters, The requirement list, in name, value mapping.
   * @return The shared pointer to the encoded interest
   */
  static shared_ptr<Interest>
  genChallengeInterest(const RequesterState& state,
                       std::vector<std::tuple<std::string, std::string>>&& parameters);

  /**
   * Decodes the responded data from the CHALLENGE interest.
   * @param state, the corresponding requester state of the request. Will be modified.
   * @param reply, the response data.
   * @throw std::runtime_error if the decoding fails or receiving an error packet.
   */
  static void
  onChallengeResponse(RequesterState& state, const Data& reply);

  /**
   * Generate the interest to fetch the issued certificate
   * @param state, the state of the request.
   * @return The shared pointer to the encoded interest
   */
  static shared_ptr<Interest>
  genCertFetchInterest(const RequesterState& state);

  /**
   * Decoded and installs the response certificate from the certificate fetch.
   * @param reply, the data replied from the certificate fetch interest.
   * @return The shared pointer to the certificate being fetched.
   */
  static shared_ptr<security::Certificate>
  onCertFetchResponse(const Data& reply);

  /**
   * End the current request session and performs cleanup if necessary.
   * @param state, the requester state for the request.
   */
  static void
  endSession(RequesterState& state);

private:
  static void
  processIfError(const Data& data);
};

} // namespace ndncert
} // namespace ndn

#endif // NDNCERT_REQUESTER_HPP
