/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2014-2018, Regents of the University of California
 *
 * NAC library is free software: you can redistribute it and/or modify it under the
 * terms of the GNU Lesser General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later version.
 *
 * NAC library 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 Lesser General Public License for more details.
 *
 * You should have received copies of the GNU General Public License and GNU Lesser
 * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
 * <http://www.gnu.org/licenses/>.
 *
 * See AUTHORS.md for complete list of NAC library authors and contributors.
 */

#ifndef NDN_NAC_ENCRYPTOR_HPP
#define NDN_NAC_ENCRYPTOR_HPP

#include "common.hpp"
#include "encrypted-content.hpp"

namespace ndn {
namespace nac {

/**
 * @brief NAC Encryptor
 *
 * Encryptor encrypts the requested content and returns ``EncryptedContent`` element.
 */
class Encryptor
{
public:
  /**
   * @param accessPrefix  NAC prefix to fetch KEK (e.g., /access/prefix/NAC/data/subset)
   * @param ckPrefix      Prefix under which Content Keys will be generated
   *                      (each will have unique version appended)
   * @param ckDataSigningInfo  SigningInfo parameters to sign CK Data
   * @param onFailure     Callback to notify application of a failure to create CK data
   *                      (failed to fetch KEK, failed to encrypt with KEK, etc.)
   * @param validator     Validation policy to ensure correctness of KEK
   * @param keyChain      KeyChain
   * @param face          Face that will be used to fetch KEK and publish CK data
   */
  Encryptor(const Name& accessPrefix,
            const Name& ckPrefix, SigningInfo ckDataSigningInfo,
            const ErrorCallback& onFailure,
            Validator& validator, KeyChain& keyChain, Face& face);

  ~Encryptor();

  /**
   * Synchronously encrypt supplied data
   *
   * If KEK has not been fetched already, this method will trigger async fetching of it.
   * After KEK successfully fetched, CK data will be automatically published.
   *
   * @todo For now, CK is being published in InMemoryStorage and can be fetched only while
   *       Encryptor instance is alive.
   *
   * The actual encryption is done synchronously, but the exact KDK name is not known
   * until KEK is fetched.
   *
   * Note that if the KDK name is already known, this method will call onReady right away.
   *
   * @return Encrypted content
   */
  EncryptedContent
  encrypt(const uint8_t* data, size_t size);

  /**
   * @brief Create a new content key and publish the corresponding CK data
   *
   * @todo Ensure that CK data packet for the old CK is published, when CK updated
   *       before KEK fetched
   */
  void
  regenerateCk(const ErrorCallback& onFailure);

public: // accessor interface for published data packets

  /** @return{ number of packets stored in in-memory storage }
   */
  size_t
  size() const
  {
    return m_ims.size();
  }

  /** @brief Returns begin iterator of the in-memory storage ordered by
   *  name with digest
   *
   *  @return{ const_iterator pointing to the beginning of m_cache }
   */
  InMemoryStorage::const_iterator
  begin() const
  {
    return m_ims.begin();
  }

  /** @brief Returns end iterator of the in-memory storage ordered by
   *  name with digest
   *
   *  @return{ const_iterator pointing to the end of m_cache }
   */
  InMemoryStorage::const_iterator
  end() const
  {
    return m_ims.end();
  }

private:
  void
  fetchKekAndPublishCkData(const std::function<void()>& onReady,
                           const ErrorCallback& onFailure,
                           size_t nTriesLeft);

  void
  makeAndPublishCkData(const ErrorCallback& onFailure);

private:
  Name m_accessPrefix;
  Name m_ckPrefix;
  Name m_ckName;
  Buffer m_ckBits;
  SigningInfo m_ckDataSigningInfo;

  bool m_isKekRetrievalInProgress;
  optional<Data> m_kek;

  InMemoryStoragePersistent m_ims; // for encrypted CKs
  const RegisteredPrefixId* m_ckRegId = nullptr;
  const PendingInterestId* m_kekPendingInterest = nullptr;

  KeyChain& m_keyChain;
  Face& m_face;
};

} // namespace nac
} // namespace ndn

#endif // NDN_NAC_ENCRYPTOR_HPP
