/* -*- 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_PIB_HPP
#define NDN_SECURITY_PIB_PIB_HPP

#include "identity-container.hpp"

namespace ndn {
namespace security {

class KeyChain;

namespace pib {

class PibImpl;

/**
 * @brief represents the PIB
 *
 * The PIB (Public Information Base) stores the public portion of a user's cryptography keys.
 * The format and location of stored information is indicated by the PibLocator.
 * The PIB is designed to work with a TPM (Trusted Platform Module) which stores private keys.
 * There is a one-to-one association between PIB and TPM, and therefore the TpmLocator is recorded
 * by the PIB to enforce this association and prevent one from operating on mismatched PIB and TPM.
 *
 * Information in the PIB is organized in a hierarchy of Identity-Key-Certificate. At the top level,
 * the Pib class provides access to identities, and allows setting a default identity. Properties of
 * an identity can be accessed after obtaining an Identity object.
 *
 * @throw PibImpl::Error when underlying implementation has non-semantic error.
 */
class Pib : noncopyable
{
public:
  friend class KeyChain;

public:
  /// @brief represents a semantic error
  class Error : public std::runtime_error
  {
  public:
    explicit
    Error(const std::string& what)
      : std::runtime_error(what)
    {
    }
  };

public:
  ~Pib();

  /**
   * @brief return the scheme of the PibLocator
   */
  std::string
  getScheme() const
  {
    return m_scheme;
  }

  /**
   * @brief Get PIB Locator
   */
  std::string
  getPibLocator() const;

  /**
   * @brief Set the corresponding TPM information to @p tpmLocator.
   *
   * If the provided @p tpmLocator is different from the existing one, PIB will be reset.
   * Otherwise, nothing will be changed.
   */
  void
  setTpmLocator(const std::string& tpmLocator);

  /**
   * @brief Get TPM Locator
   * @throws Error if TPM locator is empty
   */
  std::string
  getTpmLocator() const;

  /**
   * @brief Reset content in PIB, including reset of the TPM locator
   */
  void
  reset();

  /**
   * @brief Get an identity with name @p identityName.
   *
   * @param identityName The name for the identity to get.
   * @throw Pib::Error if the identity does not exist.
   */
  Identity
  getIdentity(const Name& identityName) const;

  /// @brief Get all the identities
  const IdentityContainer&
  getIdentities() const;

  /**
   * @brief Get the default identity.
   *
   * @return the default identity.
   * @throws Pib::Error if no default identity.
   */
  Identity&
  getDefaultIdentity() const;

NDN_CXX_PUBLIC_WITH_TESTS_ELSE_PRIVATE: // write operations should be private

  /*
   * @brief Create an identity with name @p identityName and return a reference to it.
   *
   * If there already exists an identity for the name @p identityName, then it is returned.
   * If no default identity is set, the newly created identity will be set as the default.
   *
   * @param identityName The name for the identity to be added
   */
  Identity
  addIdentity(const Name& identityName);

  /*
   * @brief Remove an identity with name @p identityName.
   *
   * @param identityName The name for the identity to be deleted
   */
  void
  removeIdentity(const Name& identityName);

  /**
   * @brief Set an identity with name @p identityName as the default identity.
   *
   * Also create the identity if it does not exist.
   *
   * @param identityName The name for the default identity.
   * @return the default identity
   */
  Identity&
  setDefaultIdentity(const Name& identityName);

NDN_CXX_PUBLIC_WITH_TESTS_ELSE_PRIVATE:
  /*
   * @brief Create a new Pib with the specified @p location
   *
   * @param scheme The scheme for the Pib
   * @param location The location for the Pib
   * @param impl The backend implementation
   */
  Pib(const std::string& scheme, const std::string& location, shared_ptr<PibImpl> impl);

  shared_ptr<PibImpl>
  getImpl()
  {
    return m_impl;
  }

protected:
  std::string m_scheme;
  std::string m_location;

  mutable bool m_hasDefaultIdentity;
  mutable Identity m_defaultIdentity;

  mutable bool m_needRefreshIdentities;
  mutable IdentityContainer m_identities;

  shared_ptr<PibImpl> m_impl;
};

} // namespace pib

using pib::Pib;

} // namespace security
} // namespace ndn

#endif // NDN_SECURITY_PIB_PIB_HPP
