/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
/**
 * Copyright (C) 2013 Regents of the University of California.
 * @author: Jeff Thompson <jefft0@remap.ucla.edu>
 * See COPYING for copyright and distribution information.
 */

#ifndef NDN_SECURITY_SEC_PUBLIC_INFO_MEMORY_HPP
#define NDN_SECURITY_SEC_PUBLIC_INFO_MEMORY_HPP

#include "../common.hpp"
#include "sec-public-info.hpp"

namespace ndn {

/**
 * @brief SecPublicInfoMemory extends SecPublicInfo and implements its methods to store identity,
 *        public key and certificate objects in memory.
 */
class SecPublicInfoMemory : public SecPublicInfo
{
public:
  class Error : public SecPublicInfo::Error
  {
  public:
    explicit
    Error(const std::string& what)
      : SecPublicInfo::Error(what)
    {
    }
  };

  virtual
  ~SecPublicInfoMemory();

  virtual bool
  doesIdentityExist(const Name& identityName);

  virtual void
  addIdentity(const Name& identityName);

  virtual bool
  revokeIdentity();

  virtual bool
  doesPublicKeyExist(const Name& keyName);

  virtual void
  addPublicKey(const Name& keyName, KeyType keyType, const PublicKey& publicKeyDer);

  virtual shared_ptr<PublicKey>
  getPublicKey(const Name& keyName);

  virtual bool
  doesCertificateExist(const Name& certificateName);

  virtual void
  addCertificate(const IdentityCertificate& certificate);

  virtual shared_ptr<IdentityCertificate>
  getCertificate(const Name& certificateName);

  virtual Name
  getDefaultIdentity();

  virtual Name
  getDefaultKeyNameForIdentity(const Name& identityName);

  virtual Name
  getDefaultCertificateNameForKey(const Name& keyName);

  virtual void
  getAllIdentities(std::vector<Name>& nameList, bool isDefault);

  virtual void
  getAllKeyNames(std::vector<Name>& nameList, bool isDefault);

  virtual void
  getAllKeyNamesOfIdentity(const Name& identity, std::vector<Name>& nameList, bool isDefault);

  virtual void
  getAllCertificateNames(std::vector<Name>& nameList, bool isDefault);

  virtual void
  getAllCertificateNamesOfKey(const Name& keyName, std::vector<Name>& nameList, bool isDefault);

protected:
  virtual void
  setDefaultIdentityInternal(const Name& identityName);

  virtual void
  setDefaultKeyNameForIdentityInternal(const Name& keyName);

  virtual void
  setDefaultCertificateNameForKeyInternal(const Name& certificateName);

  virtual void
  deleteCertificateInfo(const Name& certificateName);

  virtual void
  deletePublicKeyInfo(const Name& keyName);

  virtual void
  deleteIdentityInfo(const Name& identity);


private:
  class KeyRecord
  {
  public:
    KeyRecord(KeyType keyType, const PublicKey& key)
    : m_keyType(keyType), m_key(key)
    {
    }

    const KeyType
    getKeyType() const
    {
      return m_keyType;
    }

    const PublicKey&
    getKey()
    {
      return m_key;
    }

  private:
    KeyType   m_keyType;
    PublicKey m_key;
  };

  std::vector<std::string> m_identityStore; // A list of name URI.
  std::string m_defaultIdentity; // The default identity in m_identityStore, or "" if not defined.
  Name m_defaultKeyName;
  Name m_defaultCert;

  // The map key is the keyName.toUri()
  typedef std::map<std::string, shared_ptr<KeyRecord> > KeyStore;

  // The map key is the certificateName.toUri()
  typedef std::map<std::string, shared_ptr<IdentityCertificate> > CertificateStore;

  KeyStore m_keyStore;
  CertificateStore m_certificateStore;
};

} // namespace ndn

#endif //NDN_SECURITY_SEC_PUBLIC_INFO_MEMORY_HPP
