/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
/*
 * Copyright (c) 2011 University of California, Los Angeles
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation;
 *
 * This program 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 this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * Authors: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
 */

#ifndef NDN_FACE_H
#define NDN_FACE_H

#include <ostream>
#include <algorithm>

#include "ns3/ptr.h"
#include "ns3/object.h"
#include "ns3/nstime.h"
#include "ns3/type-id.h"
#include "ns3/traced-callback.h"
#include "ns3/ndn-name.hpp"

namespace ns3 {

class Packet;
class Node;

namespace ndn {

class Interest;
class Data;

/**
 * \ingroup ndn
 * \defgroup ndn-face Faces
 */
/**
 * \ingroup ndn-face
 * \brief Virtual class defining NDN face
 *
 * This class defines basic functionality of NDN face. Face is core
 * component responsible for actual delivery of data packet to and
 * from NDN stack
 *
 * \see ndn::AppFace, ndn::NetDeviceFace
 */
class Face : public Object {
public:
  static TypeId
  GetTypeId();

  /**
   * \brief NDN protocol handlers
   *
   * \param face Face from which packet has been received
   * \param packet Original packet
   */
  typedef Callback<void, Ptr<Face>, Ptr<Interest>> InterestHandler;
  typedef Callback<void, Ptr<Face>, Ptr<Data>> DataHandler;

  /**
   * \brief Default constructor
   */
  Face(Ptr<Node> node);
  virtual ~Face();

  /**
   * @brief Get node to which this face is associated
   */
  Ptr<Node>
  GetNode() const;

  ////////////////////////////////////////////////////////////////////

  /**
   * \brief Register callback to call when new packet arrives on the face
   *
   * This method should call protocol-dependent registration function
   */
  virtual void
  RegisterProtocolHandlers(const InterestHandler& interestHandler, const DataHandler& dataHandler);

  /**
   * \brief Un-Register callback to call when new packet arrives on the face
   *
   * This method should call protocol-dependent registration function
   */
  virtual void
  UnRegisterProtocolHandlers();

  /**
   * @brief Send out interest through the face
   * @param interest Interest to send out
   * @param packet "payload" that is attached to the interest (can carry some packet tags)
   *
   * @returns true if interest is considered to be send out (enqueued)
   */
  virtual bool
  SendInterest(Ptr<const Interest> interest);

  /**
   * @brief Send out Dat packet through the face
   * @param data Data packet to send out
   * @param packet Data packet payload, can also carry packet tags
   *
   * @returns true if Data packet is considered to be send out (enqueued)
   */
  virtual bool
  SendData(Ptr<const Data> data);

  /**
   * \brief Receive interest from application or another node and forward it up to the NDN stack
   *
   * By default it is called from inside Receive method, but can be used directly, if appropriate
   */
  virtual bool
  ReceiveInterest(Ptr<Interest> interest);

  /**
   * \brief Receive Data packet from application or another node and forward it up to the NDN stack
   *
   * By default it is called from inside Receive method, but can be used directly, if appropriate
   */
  virtual bool
  ReceiveData(Ptr<Data> data);
  ////////////////////////////////////////////////////////////////////

  /**
   * \brief Assign routing/forwarding metric with face
   *
   * \param metric configured routing metric (cost) of this face
   */
  virtual void
  SetMetric(uint16_t metric);

  /**
   * \brief Get routing/forwarding metric assigned to the face
   *
   * \returns configured routing/forwarding metric (cost) of this face
   */
  virtual uint16_t
  GetMetric(void) const;

  /**
   * These are face states and may be distinct from actual lower-layer
   * device states, such as found in real implementations (where the
   * device may be down but ndn face state is still up).
   */

  /**
   * \brief Enable or disable this face
   */
  inline void
  SetUp(bool up = true);

  /**
   * \brief Returns true if this face is enabled, false otherwise.
   */
  inline bool
  IsUp() const;

  /**
   * @brief Get face flags
   *
   * Face flags may indicate various properties of the face.  For example, if the face is an
   *application face,
   * than the returned flags have Face::APPLICATION bit set.
   *
   * @see ndn::Face::Flags for the list of currently defined face flags
   */
  inline uint32_t
  GetFlags() const;

  /**
   * @brief List of currently defined face flags
   */
  enum Flags {
    APPLICATION = 1 ///< @brief An application face
  };

  /**
   * @brief Print information about the face into the stream
   * @param os stream to write information to
   */
  virtual std::ostream&
  Print(std::ostream& os) const;

  /**
   * \brief Set face Id
   *
   * Id is purely informative and should not be used for any other purpose
   *
   * \param id id to set
   */
  inline void
  SetId(uint32_t id);

  /**
   * \brief Get face Id
   *
   * Id is purely informative and should not be used for any other purpose
   *
   * \returns id id to set
   */
  inline uint32_t
  GetId() const;

  /**
   * \brief Compare two faces. Only two faces on the same node could be compared.
   *
   * Internal index is used for comparison.
   */
  bool
  operator==(const Face& face) const;

  /**
   * \brief Compare two faces. Only two faces on the same node could be compared.
   *
   * Internal index is used for comparison.
   */
  inline bool
  operator!=(const Face& face) const;

  /**
   * \brief Compare two faces. Only two faces on the same node could be compared.
   *
   * Internal index is used for comparison.
   */
  bool
  operator<(const Face& face) const;

protected:
  /**
   * @brief Send packet down to the stack (towards app or network)
   */
  virtual bool
  Send(Ptr<Packet> packet);

  /**
   * @brief Send packet up to the stack (towards forwarding strategy)
   */
  virtual bool
  Receive(Ptr<const Packet> p);

  /**
   * @brief Set face flags
   */
  void
  SetFlags(uint32_t flags);

private:
  Face(const Face&); ///< \brief Disabled copy constructor
  Face&
  operator=(const Face&); ///< \brief Disabled copy operator

protected:
  Ptr<Node> m_node; ///< \brief Smart pointer to Node

private:
  InterestHandler m_upstreamInterestHandler;
  DataHandler m_upstreamDataHandler;
  bool m_ifup;
  uint32_t m_id;     ///< \brief id of the interface in NDN stack (per-node uniqueness)
  uint16_t m_metric; ///< \brief metric of the face
  uint32_t m_flags;  ///< @brief faces flags (e.g., APPLICATION)
};

std::ostream&
operator<<(std::ostream& os, const Face& face);

inline bool
Face::IsUp(void) const
{
  return m_ifup;
}

inline void
Face::SetUp(bool up /* = true*/)
{
  m_ifup = up;
}

inline uint32_t
Face::GetFlags() const
{
  return m_flags;
}

inline bool
operator<(const Ptr<Face>& lhs, const Ptr<Face>& rhs)
{
  return *lhs < *rhs;
}

void
Face::SetId(uint32_t id)
{
  m_id = id;
}

uint32_t
Face::GetId() const
{
  return m_id;
}

inline bool
Face::operator!= (const Face &face) const
{
  return !(*this == face);
}

} // namespace ndn
} // namespace ns3

#endif // NDN_FACE_H
