/* -*- 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.
   *
   * @throw std::invalid_argument certificate name does not match key name
   * @throw Pib::Error a certificate with the same name already exists
   */
  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
