/* -*- 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_DELEGATION_LIST_HPP
#define NDN_DELEGATION_LIST_HPP

#include "delegation.hpp"
#include <initializer_list>

namespace ndn {

/** \brief represents a list of Delegations
 *  \sa https://named-data.net/doc/ndn-tlv/link.html
 *
 *  Delegations are stored in an std::vector, under the assumption that there is usually only a
 *  small number of Delegations, so that copying is acceptable when they are modified.
 */
class DelegationList
{
public:
  class Error : public tlv::Error
  {
  public:
    explicit
    Error(const std::string& what);

    Error(const std::string& what, const std::exception& innerException);
  };

  /** \brief construct an empty DelegationList
   */
  DelegationList();

  /** \brief construct a sorted DelegationList with specified delegations
   *
   *  This is equivalent to inserting each delegation into an empty DelegationList with INS_REPLACE
   *  conflict resolution.
   */
  DelegationList(std::initializer_list<Delegation> dels);

  /** \brief decode a DelegationList
   *  \sa wireDecode
   */
  explicit
  DelegationList(const Block& block, bool wantSort = true);

  /** \brief encode into wire format
   *  \param encoder either an EncodingBuffer or an EncodingEstimator
   *  \param type TLV-TYPE code, either Content (for \p Link) or ForwardingHint
   *  \throw std::invalid_argument \p type is invalid
   *  \throw Error there is no Delegation
   */
  template<encoding::Tag TAG>
  size_t
  wireEncode(EncodingImpl<TAG>& encoder, uint32_t type = tlv::ForwardingHint) const;

  /** \brief decode a DelegationList
   *  \param block either a Content block (from \p Link) or a ForwardingHint block
   *  \param wantSort if true, delegations are sorted
   *  \throw Error the block cannot be parsed as a list of Delegations
   */
  void
  wireDecode(const Block& block, bool wantSort = true);

  bool
  isSorted() const
  {
    return m_isSorted;
  }

  using const_iterator = std::vector<Delegation>::const_iterator;

  const_iterator
  begin() const
  {
    return m_dels.begin();
  }

  const_iterator
  end() const
  {
    return m_dels.end();
  }

  size_t
  size() const
  {
    return m_dels.size();
  }

  /** \brief get the i-th delegation
   *  \pre i < size()
   */
  const Delegation&
  operator[](size_t i) const
  {
    BOOST_ASSERT(i < size());
    return m_dels[i];
  }

  /** \brief get the i-th delegation
   *  \throw std::out_of_range i >= size()
   */
  const Delegation&
  at(size_t i) const
  {
    return m_dels.at(i);
  }

public: // modifiers
  /** \brief sort the delegation list
   *  \post isSorted() == true
   *  \post Delegations are sorted in increasing preference order.
   *
   *  A DelegationList can be constructed as sorted or unsorted. In most cases, it is recommended
   *  to use a sorted DelegationList. An unsorted DelegationList is useful for extracting the i-th
   *  delegation from a received ForwardingHint or Link object.
   *
   *  This method turns an unsorted DelegationList into a sorted DelegationList.
   *  If access to unsorted DelegationList is not needed, it is more efficient to sort the
   *  DelegationList in wireDecode.
   */
  void
  sort();

  /** \brief what to do when inserting a duplicate name
   */
  enum InsertConflictResolution {
    /** \brief existing delegation(s) with the same name are replaced with the new delegation
     */
    INS_REPLACE,

    /** \brief multiple delegations with the same name are kept in the DelegationList
     *  \note This is NOT RECOMMENDED by Link specification.
     */
    INS_APPEND,

    /** \brief new delegation is not inserted if an existing delegation has the same name
     */
    INS_SKIP
  };

  /** \brief insert Delegation
   *  \return whether inserted
   */
  bool
  insert(uint64_t preference, const Name& name,
         InsertConflictResolution onConflict = INS_REPLACE);

  /** \brief insert Delegation
   *  \return whether inserted
   */
  bool
  insert(const Delegation& del, InsertConflictResolution onConflict = INS_REPLACE)
  {
    return this->insert(del.preference, del.name, onConflict);
  }

  /** \brief delete Delegation(s) with specified preference and name
   *  \return count of erased Delegation(s)
   */
  size_t
  erase(uint64_t preference, const Name& name)
  {
    return this->eraseImpl(preference, name);
  }

  /** \brief delete Delegation(s) with matching preference and name
   *  \return count of erased Delegation(s)
   */
  size_t
  erase(const Delegation& del)
  {
    return this->eraseImpl(del.preference, del.name);
  }

  /** \brief erase Delegation(s) with specified name
   *  \return count of erased Delegation(s)
   */
  size_t
  erase(const Name& name)
  {
    return this->eraseImpl(nullopt, name);
  }

private:
  static bool
  isValidTlvType(uint32_t type);

  void
  insertImpl(uint64_t preference, const Name& name);

  size_t
  eraseImpl(optional<uint64_t> preference, const Name& name);

private:
  bool m_isSorted;

  /** \brief delegation container; its contents are sorted when \p m_isSorted is true
   *  \note This container is a member field rather than a base class, in order to ensure contents
   *        are sorted when \p m_isSorted is true.
   *  \note A vector is chosen instead of a std::set, so that the container can be unsorted when
   *        \p m_isSorted is false. This container is expected to have less than seven items, and
   *        therefore the overhead of moving items during insertion and deletion is small.
   */
  std::vector<Delegation> m_dels;

  friend bool operator==(const DelegationList&, const DelegationList&);
};

/** \brief compare whether two DelegationLists are equal
 *  \note Order matters! If two DelegationLists contain the same Delegations but at least one is
 *        unsorted, they may compare unequal if the Delegations appear in different order.
 */
bool
operator==(const DelegationList& lhs, const DelegationList& rhs);

inline bool
operator!=(const DelegationList& lhs, const DelegationList& rhs)
{
  return !(lhs == rhs);
}

std::ostream&
operator<<(std::ostream& os, const DelegationList& dl);

} // namespace ndn

#endif // NDN_DELEGATION_LIST_HPP
