/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2013-2024 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_CXX_SECURITY_TRUST_ANCHOR_CONTAINER_HPP
#define NDN_CXX_SECURITY_TRUST_ANCHOR_CONTAINER_HPP

#include "ndn-cxx/interest.hpp"
#include "ndn-cxx/security/certificate.hpp"
#include "ndn-cxx/security/trust-anchor-group.hpp"

#include <boost/multi_index_container.hpp>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/mem_fun.hpp>

namespace ndn::security {

/**
 * @brief A container for trust anchors.
 *
 * There are two kinds of anchors:
 * - static anchors that are permanent for the lifetime of the container
 * - dynamic anchors that are periodically updated.
 *
 * Trust anchors are organized in groups. Each group has a unique group id.  The same anchor
 * certificate (same name without considering the implicit digest) can be inserted into
 * multiple groups, but no more than once into each.
 *
 * Dynamic groups are created using the appropriate TrustAnchorContainer::insert method. Once
 * created, the dynamic anchor group cannot be updated.
 *
 * The returned pointer to Certificate from `find` methods is only guaranteed to be valid until
 * the next invocation of `find` and may be invalidated afterwards.
 */
class TrustAnchorContainer : noncopyable
{
public:
  class Error : public std::runtime_error
  {
  public:
    using std::runtime_error::runtime_error;
  };

  /**
   * @brief Insert a static trust anchor.
   *
   * @param groupId  Certificate group id.
   * @param cert     Certificate to insert.
   *
   * If @p cert (same name without considering implicit digest) already exists in the group @p
   * groupId, this method has no effect.
   *
   * @throw Error @p groupId is a dynamic anchor group .
   */
  void
  insert(const std::string& groupId, Certificate&& cert);

  /**
   * @brief Insert dynamic trust anchors from path.
   *
   * @param groupId        Certificate group id, must not be empty.
   * @param path           Specifies the path to load the trust anchors.
   * @param refreshPeriod  Refresh period for the trust anchors, must be positive.
   *                       Relevant trust anchors will only be updated when find is called
   * @param isDir          Tells whether the path is a directory or a single file.
   *
   * @throw std::invalid_argument @p refreshPeriod is not positive
   * @throw Error a group with @p groupId already exists
   */
  void
  insert(const std::string& groupId, const std::filesystem::path& path,
         time::nanoseconds refreshPeriod, bool isDir = false);

  /**
   * @brief Remove all static or dynamic anchors.
   */
  void
  clear();

  /**
   * @brief Search for certificate across all groups (longest prefix match).
   * @param keyName  Key name prefix for searching the certificate.
   * @return The found certificate, nullptr if not found.
   *
   * @note The returned value may be invalidated after next call to one of `find` methods.
   */
  const Certificate*
  find(const Name& keyName) const;

  /**
   * @brief Find certificate given interest.
   * @param interest  The input interest packet.
   * @return The found certificate, nullptr if not found.
   *
   * @note The returned value may be invalidated after next call to one of `find` methods.
   * @note Interest with implicit digest is not supported.
   */
  const Certificate*
  find(const Interest& interest) const;

  /**
   * @brief Get trusted anchor group.
   * @throw Error @p groupId does not exist
   */
  TrustAnchorGroup&
  getGroup(const std::string& groupId) const;

  /**
   * @brief Get number of trust anchors across all groups.
   */
  size_t
  size() const;

private:
  void
  refresh();

private:
  using AnchorContainerBase = boost::multi_index::multi_index_container<
    Certificate,
    boost::multi_index::indexed_by<
      boost::multi_index::ordered_unique<
        boost::multi_index::const_mem_fun<Data, const Name&, &Data::getName>
      >
    >
  >;

  class AnchorContainer : public CertContainerInterface,
                          public AnchorContainerBase
  {
  public:
    void
    add(Certificate&& cert) final;

    void
    remove(const Name& certName) final;

    void
    clear();
  };

  using GroupContainer = boost::multi_index::multi_index_container<
    shared_ptr<TrustAnchorGroup>,
    boost::multi_index::indexed_by<
      boost::multi_index::hashed_unique<
        boost::multi_index::const_mem_fun<TrustAnchorGroup, const std::string&, &TrustAnchorGroup::getId>
      >
    >
  >;

  GroupContainer m_groups;
  AnchorContainer m_anchors;
};

} // namespace ndn::security

#endif // NDN_CXX_SECURITY_TRUST_ANCHOR_CONTAINER_HPP
