/* -*- 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<std::pair<Name, int>>& 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
