/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2014-2017,  The University of Memphis,
 *                           Regents of the University of California,
 *                           Arizona Board of Regents.
 *
 * This file is part of NLSR (Named-data Link State Routing).
 * See AUTHORS.md for complete list of NLSR authors and contributors.
 *
 * NLSR 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.
 *
 * NLSR 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
 * NLSR, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
 **/

#ifndef NLSR_ADJACENCY_LIST_HPP
#define NLSR_ADJACENCY_LIST_HPP

#include "adjacent.hpp"

#include <list>
#include <boost/cstdint.hpp>
#include <ndn-cxx/common.hpp>

namespace nlsr {

class AdjacencyList
{
public:
  typedef std::list<Adjacent>::const_iterator const_iterator;
  typedef std::list<Adjacent>::iterator iterator;

  AdjacencyList();
  ~AdjacencyList();

  /*! \brief Inserts an adjacency into the list.

    \param adjacent The adjacency that we want to add to this list.

    \retval 0 Indicates success.
    \retval 1 Indicates failure.

    This function attempts to insert the supplied adjacency into this
    object, which is an adjacency list.
   */
  int32_t
  insert(Adjacent& adjacent);

  /*! \brief Sets the status of an adjacency.

    \param adjName The adjacency in this list you want to change the status of.

    \param s The status to change to.

    \return A boolean indicating whether an adjacency was
    updated. This is false if s is not in the list.
   */
  bool
  updateAdjacentStatus(const ndn::Name& adjName, Adjacent::Status s);

  int32_t
  updateAdjacentLinkCost(const ndn::Name& adjName, double lc);

  std::list<Adjacent>&
  getAdjList();

  bool
  isNeighbor(const ndn::Name& adjName);

  void
  incrementTimedOutInterestCount(const ndn::Name& neighbor);

  int32_t
  getTimedOutInterestCount(const ndn::Name& neighbor);

  Adjacent::Status
  getStatusOfNeighbor(const ndn::Name& neighbor);

  void
  setStatusOfNeighbor(const ndn::Name& neighbor, Adjacent::Status status);

  void
  setTimedOutInterestCount(const ndn::Name& neighbor, uint32_t count);

  /*! \brief Copies the adjacencies in a list to this one.

    \param adl The adjacency list, the entries of which we want to
    copy into this object.

    Copies the entries contained in one list into this object.
   */
  void
  addAdjacents(AdjacencyList& adl);

  /*! \brief Determines whether this list can be used to build an adj. LSA.
    \param interestRetryNo The maximum number of hello-interest
      retries to contact a neighbor.

    \return Returns a boolean indicating whether this list can be used
    to build an adj. LSA.

    Determines whether this adjacency list object could be used to
    build an adjacency LSA. An LSA is buildable when the status of all
    neighbors is known. A neighbor's status is known when their status
    is ACTIVE, or INACTIVE and some number of hello interests
    (specified by nlsr::ConfParameter::getInterestRetryNumber()) have
    failed. To be explicit, a neighbor's status is unknown if we are
    still sending hello interests.
   */
  bool
  isAdjLsaBuildable(const uint32_t interestRetryNo) const;

  int32_t
  getNumOfActiveNeighbor();

  Adjacent
  getAdjacent(const ndn::Name& adjName);

  bool
  operator==(AdjacencyList& adl);

  size_t
  getSize()
  {
    return m_adjList.size();
  }

  void
  reset()
  {
    if (m_adjList.size() > 0) {
      m_adjList.clear();
    }
  }

  AdjacencyList::iterator
  findAdjacent(const ndn::Name& adjName);

  AdjacencyList::iterator
  findAdjacent(uint64_t faceId);

  AdjacencyList::iterator
  findAdjacent(const ndn::util::FaceUri& faceUri);

  /*! \brief Hack to stop developers from using this function

    It is here so that faceUri cannot be passed in as string,
    converted to Name and findAdjacent(Name) be used.
    So when faceUri is passed as string this will cause a compile error
   */
  template <typename T = float> void
  findAdjacent(const std::string& faceUri)
  {
    BOOST_STATIC_ASSERT_MSG(std::is_integral<T>::value,
      "Don't use std::string with findAdjacent!");
  }

  uint64_t
  getFaceId(const ndn::util::FaceUri& faceUri);

  void
  writeLog();

public:
  const_iterator
  begin() const
  {
    return m_adjList.begin();
  }

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

private:
  iterator
  find(const ndn::Name& adjName);

private:
  std::list<Adjacent> m_adjList;
};

} // namespace nlsr
#endif // NLSR_ADJACENCY_LIST_HPP
