/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2014-2018, Regents of the University of California.
 *
 * This file is part of NDN repo-ng (Next generation of NDN repository).
 * See AUTHORS.md for complete list of repo-ng authors and contributors.
 *
 * repo-ng is free software: you can redistribute it and/or modify it under the terms
 * of the GNU General Public License as published by the Free Software Foundation,
 * either version 3 of the License, or (at your option) any later version.
 *
 * repo-ng 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * repo-ng, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef REPO_STORAGE_INDEX_HPP
#define REPO_STORAGE_INDEX_HPP

#include "../common.hpp"

#include <set>

namespace repo {

class Index : noncopyable
{
public:
  class Error : public std::runtime_error
  {
  public:
    explicit
    Error(const std::string& what)
      : std::runtime_error(what)
    {
    }
  };

  class Entry
  {
  public:
    class Error : public std::runtime_error
    {
    public:
      explicit
      Error(const std::string& what)
        : std::runtime_error(what)
      {
      }
    };

  public:
    /**
     * @brief used by set to construct node
     */
    Entry() = default;

    /**
     * @brief construct Entry by data and id number
     */
    Entry(const Data& data, int64_t id);

    /**
     * @brief construct Entry by fullName, keyLocator and id number
     */
    Entry(const Name& fullName, const KeyLocator& keyLocator, int64_t id);

    /**
     * @brief construct Entry by fullName, keyLocatorHash and id number
     * @param  fullName        full name with digest computed from data
     * @param  keyLocatorHash  keyLocator hashed by sha256
     * @param  id              record ID from database
     */
    Entry(const Name& fullName, const ndn::ConstBufferPtr& keyLocatorHash, int64_t id);

    /**
     *  @brief implicit construct Entry by full name
     *
     *  Allow implicit conversion from Name for set lookups by Name
     */
    Entry(const Name& name);

    /**
     *  @brief get the name of entry
     */
    const Name&
    getName() const
    {
      return m_name;
    }

    /**
     *  @brief get the keyLocator hash value of the entry
     */
    const ndn::ConstBufferPtr&
    getKeyLocatorHash() const
    {
      return m_keyLocatorHash;
    }

    /**
     *  @brief get record ID from database
     */
    int64_t
    getId() const
    {
      return m_id;
    }

    bool
    operator>(const Entry& entry) const
    {
      return m_name > entry.getName();
    }

    bool
    operator<(const Entry& entry) const
    {
      return m_name < entry.getName();
    }

    bool
    operator==(const Entry& entry) const
    {
      return m_name == entry.getName();
    }

    bool
    operator!=(const Entry& entry) const
    {
      return m_name != entry.getName();
    }

  private:
    Name m_name;
    ndn::ConstBufferPtr m_keyLocatorHash;
    int64_t m_id;
  };

private:
  typedef std::set<Entry> IndexContainer;

public:
  explicit
  Index(size_t nMaxPackets);

  /**
   *  @brief insert entries into index
   *  @param  data    used to construct entries
   *  @param  id      obtained from database
   */
  bool
  insert(const Data& data, int64_t id);

  /**
   *  @brief insert entries into index
   *  @param  data    used to construct entries
   *  @param  id      obtained from database
   */
  bool
  insert(const Name& fullName, int64_t id,
         const ndn::ConstBufferPtr& keyLocatorHash);

  /**
   *  @brief erase the entry in index by its fullname
   */
  bool
  erase(const Name& fullName);

  /** @brief find the Entry for best match of an Interest
   * @return ID and fullName of the Entry, or (0,ignored) if not found
   */
  std::pair<int64_t, Name>
  find(const Interest& interest) const;

  /** @brief find the first Entry under a Name prefix
   * @return ID and fullName of the Entry, or (0,ignored) if not found
   */
  std::pair<int64_t, Name>
  find(const Name& name) const;

  /**
   *  @brief determine whether same Data is already in the index
   *  @return true if identical Data exists, false otherwise
   */
  bool
  hasData(const Data& data) const;

  /**
    *  @brief compute the hash value of keyLocator
    */
  static const ndn::ConstBufferPtr
  computeKeyLocatorHash(const KeyLocator& keyLocator);

  size_t
  size() const
  {
    return m_size;
  }

private:
  /**
   *  @brief select entries which satisfy the selectors in interest and return their name
   *  @param  interest   used to select entries by comparing the name and checking selectors
   *  @param  idName    save the id and name of found entries
   *  @param  startingPoint the entry whose name is equal or larger than the interest name
   */
  std::pair<int64_t, Name>
  selectChild(const Interest& interest,
              IndexContainer::const_iterator startingPoint) const;

  /**
   *  @brief check whether the index is full
   */
  bool
  isFull() const
  {
    return m_size >= m_maxPackets;
  }

  /**
   *  @brief find the first entry with the prefix
   *  @param  prefix        used to request the entries
   *  @param  startingPoint the entry whose name is equal or larger than the interest name
   *  @return int64_t  the id number of found entry
   *  @return Name     the name of found entry
   */
  std::pair<int64_t, Name>
  findFirstEntry(const Name& prefix,
                 IndexContainer::const_iterator startingPoint) const;

private:
  IndexContainer m_indexContainer;
  size_t m_maxPackets;
  size_t m_size;
};

} // namespace repo

#endif // REPO_STORAGE_INDEX_HPP
