/* -*- 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();

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

  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
