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

#include "ndn-cxx/detail/common.hpp"
#include "ndn-cxx/util/signal.hpp"

#include <atomic>

namespace ndn {

using RecordId = uintptr_t;

template<typename T>
class RecordContainer;

/** \brief Template of PendingInterest, RegisteredPrefix, and InterestFilterRecord.
 *  \tparam T concrete type
 */
template<typename T>
class RecordBase : noncopyable
{
public:
  RecordId
  getId() const
  {
    BOOST_ASSERT(m_id != 0);
    return m_id;
  }

protected:
  ~RecordBase() = default;

  /** \brief Delete this record from the container.
   */
  void
  deleteSelf()
  {
    BOOST_ASSERT(m_container != nullptr);
    m_container->erase(m_id);
  }

private:
  RecordContainer<T>* m_container = nullptr;
  RecordId m_id = 0;
  friend RecordContainer<T>;
};

/** \brief Container of PendingInterest, RegisteredPrefix, or InterestFilterRecord.
 *  \tparam T record type
 */
template<typename T>
class RecordContainer
{
public:
  using Record = T;
  using Container = std::map<RecordId, Record>;

  /** \brief Retrieve record by ID.
   */
  Record*
  get(RecordId id)
  {
    auto i = m_container.find(id);
    if (i == m_container.end()) {
      return nullptr;
    }
    return &i->second;
  }

  /** \brief Insert a record with given ID.
   */
  template<typename ...TArgs>
  Record&
  put(RecordId id, TArgs&&... args)
  {
    BOOST_ASSERT(id != 0);
    auto it = m_container.emplace(std::piecewise_construct, std::forward_as_tuple(id),
                                  std::forward_as_tuple(std::forward<decltype(args)>(args)...));
    BOOST_ASSERT(it.second);

    Record& record = it.first->second;
    record.m_container = this;
    record.m_id = id;
    return record;
  }

  RecordId
  allocateId()
  {
    return ++m_lastId;
  }

  /** \brief Insert a record with newly assigned ID.
   */
  template<typename ...TArgs>
  Record&
  insert(TArgs&&... args)
  {
    return put(allocateId(), std::forward<decltype(args)>(args)...);
  }

  void
  erase(RecordId id)
  {
    m_container.erase(id);
    if (empty()) {
      this->onEmpty();
    }
  }

  void
  clear()
  {
    m_container.clear();
    this->onEmpty();
  }

  /** \brief Visit all records with the option to erase.
   *  \tparam Visitor function of type 'bool f(Record& record)'
   *  \param f visitor function, return true to erase record
   */
  template<typename Visitor>
  void
  removeIf(const Visitor& f)
  {
    for (auto i = m_container.begin(); i != m_container.end(); ) {
      bool wantErase = f(i->second);
      if (wantErase) {
        i = m_container.erase(i);
      }
      else {
        ++i;
      }
    }
    if (empty()) {
      this->onEmpty();
    }
  }

  /** \brief Visit all records.
   *  \tparam Visitor function of type 'void f(Record& record)'
   *  \param f visitor function
   */
  template<typename Visitor>
  void
  forEach(const Visitor& f)
  {
    removeIf([&f] (Record& record) {
      f(record);
      return false;
    });
  }

  bool
  empty() const noexcept
  {
    return m_container.empty();
  }

  size_t
  size() const noexcept
  {
    return m_container.size();
  }

public:
  /** \brief Signals when container becomes empty
   */
  util::Signal<RecordContainer<T>> onEmpty;

private:
  Container m_container;
  std::atomic<RecordId> m_lastId{0};
};

} // namespace ndn

#endif // NDN_IMPL_RECORD_CONTAINER_HPP
