/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2013-2017 Regents of the University of California.
 *
 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
 *
 * ndn-cxx 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.
 *
 * ndn-cxx 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 ndn-cxx authors and contributors.
 */

#ifndef NDN_SECURITY_PIB_DETAIL_KEY_IMPL_HPP
#define NDN_SECURITY_PIB_DETAIL_KEY_IMPL_HPP

#include "../../../data.hpp"
#include "../certificate-container.hpp"
#include "../../security-common.hpp"

namespace ndn {
namespace security {
namespace pib {

class PibImpl;

namespace detail {

/**
 * @brief Backend instance of Key
 *
 * An Key has only one backend instance, but may have multiple frontend handles.
 * Each frontend handle is associated with the only one backend KeyImpl.
 *
 * @throw PibImpl::Error when underlying implementation has non-semantic error.
 */
class KeyImpl : noncopyable
{
public:
  /**
   * @brief Create a KeyImpl with @p keyName.
   *
   * If the key does not exist in the backend, create it in backend.
   *
   * @param keyName The name of the key.
   * @param key The public key to add.
   * @param keyLen The length of the key.
   * @param impl The Pib backend implementation.
   * @throw Pib::Error a key with the same @p keyName already exists.
   */
  KeyImpl(const Name& keyName, const uint8_t* key, size_t keyLen, shared_ptr<PibImpl> impl);

  /**
   * @brief Create a KeyImpl with @p keyName.
   *
   * @param keyName The name of the key.
   * @param impl The Pib backend implementation.
   * @throw Pib::Error the key does not exist.
   */
  KeyImpl(const Name& keyName, shared_ptr<PibImpl> impl);

  /// @brief Get the name of the key.
  const Name&
  getName() const
  {
    return m_keyName;
  }

  /**
   * @brief Get the name of the belonging identity.
   */
  const Name&
  getIdentity() const
  {
    return m_identity;
  }

  /**
   * @brief Get key type
   */
  KeyType
  getKeyType() const
  {
    return m_keyType;
  }

  /**
   * @brief Get public key bits
   */
  const Buffer&
  getPublicKey() const
  {
    return m_key;
  }

  /**
   * @brief Add @p certificate.
   *
   * If no default certificate is set before, the new certificate will be set as the default
   * certificate of the key.
   *
   * If a certificate with the same name (without implicit digest) already exists, overwrite
   * the certificate.
   *
   * @throw std::invalid_argument certificate name does not match key name
   */
  void
  addCertificate(const v2::Certificate& certificate);

  /**
   * @brief Remove a certificate with @p certName
   * @throw std::invalid_argument @p certName does not match key name
   */
  void
  removeCertificate(const Name& certName);

  /**
   * @brief Get a certificate with @p certName
   * @throw std::invalid_argument @p certName does not match key name
   * @throw Pib::Error the certificate does not exist.
   */
  v2::Certificate
  getCertificate(const Name& certName) const;

  /// @brief Get all the certificates for this key.
  const CertificateContainer&
  getCertificates() const;

  /**
   * @brief Set an existing one with @p certName as the default certificate
   * @throw std::invalid_argument @p certName does not match key name
   * @throw Pib::Error the certificate does not exist.
   * @return the default certificate
   */
  const v2::Certificate&
  setDefaultCertificate(const Name& certName);

  /**
   * @brief Add @p certificate and set it as the default certificate of the key
   * @throw std::invalid_argument @p certificate does not match key name
   * @throw Pib::Error the certificate with the same name already exists.
   * @return the default certificate
   */
  const v2::Certificate&
  setDefaultCertificate(const v2::Certificate& certificate);

  /**
   * @brief Get the default certificate for this Key.
   * @throw Pib::Error the default certificate does not exist.
   */
  const v2::Certificate&
  getDefaultCertificate() const;

private:
  Name m_identity;
  Name m_keyName;
  Buffer m_key;
  KeyType m_keyType;

  mutable bool m_isDefaultCertificateLoaded;
  mutable v2::Certificate m_defaultCertificate;

  CertificateContainer m_certificates;

  shared_ptr<PibImpl> m_impl;
};

} // namespace detail
} // namespace pib
} // namespace security
} // namespace ndn

#endif // NDN_SECURITY_PIB_DETAIL_KEY_IMPL_HPP
