/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2014-2022,  Regents of the University of California,
 *                           Arizona Board of Regents,
 *                           Colorado State University,
 *                           University Pierre & Marie Curie, Sorbonne University,
 *                           Washington University in St. Louis,
 *                           Beijing Institute of Technology,
 *                           The University of Memphis.
 *
 * This file is part of NFD (Named Data Networking Forwarding Daemon).
 * See AUTHORS.md for complete list of NFD authors and contributors.
 *
 * NFD 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.
 *
 * NFD 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
 * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef NFD_DAEMON_FACE_TRANSPORT_HPP
#define NFD_DAEMON_FACE_TRANSPORT_HPP

#include "face-common.hpp"
#include "common/counter.hpp"

namespace nfd::face {

/**
 * \brief Indicates the state of a transport.
 */
enum class TransportState {
  NONE,
  UP, ///< the transport is up and can transmit packets
  DOWN, ///< the transport is temporarily down, and is being recovered
  CLOSING, ///< the transport is being closed gracefully, either by the peer or by a call to close()
  FAILED, ///< the transport is being closed due to a failure
  CLOSED ///< the transport is closed, and can be safely deallocated
};

std::ostream&
operator<<(std::ostream& os, TransportState state);

/** \brief Counters provided by a transport.
 *  \note The type name TransportCounters is an implementation detail.
 *        Use Transport::Counters in public API.
 */
class TransportCounters
{
public:
  /** \brief count of incoming packets
   *
   *  A 'packet' typically means a top-level TLV block.
   *  For a datagram-based transport, an incoming packet that cannot be parsed as TLV
   *  would not be counted.
   */
  PacketCounter nInPackets;

  /** \brief count of outgoing packets
   *
   *  A 'packet' typically means a top-level TLV block.
   *  This counter is incremented only if transport is UP.
   */
  PacketCounter nOutPackets;

  /** \brief total incoming bytes
   *
   *  This counter includes headers imposed by NFD (such as NDNLP),
   *  but excludes overhead of underlying protocol (such as IP header).
   *  For a datagram-based transport, an incoming packet that cannot be parsed as TLV
   *  would not be counted.
   */
  ByteCounter nInBytes;

  /** \brief total outgoing bytes
   *
   *  This counter includes headers imposed by NFD (such as NDNLP),
   *  but excludes overhead of underlying protocol (such as IP header).
   *  This counter is increased only if transport is UP.
   */
  ByteCounter nOutBytes;
};

/**
 * \brief Indicates that the transport has no limit on payload size
 */
inline constexpr ssize_t MTU_UNLIMITED = -1;

/**
 * \brief (for internal use) Indicates that the MTU field is unset
 */
inline constexpr ssize_t MTU_INVALID = -2;

/**
 * \brief Indicates that the transport does not support reading the queue capacity/length
 */
inline constexpr ssize_t QUEUE_UNSUPPORTED = -1;

/**
 * \brief Indicates that the transport was unable to retrieve the queue capacity/length
 */
inline constexpr ssize_t QUEUE_ERROR = -2;

/**
 * \brief The lower half of a Face.
 * \sa Face
 */
class Transport : protected virtual TransportCounters, noncopyable
{
public:
  /** \brief Counters provided by a transport.
   *  \sa TransportCounters
   */
  using Counters = TransportCounters;

  /** \brief Default constructor.
   *
   *  This constructor initializes static properties to invalid values.
   *  Subclass constructor must explicitly set every static property.
   *
   *  This constructor initializes TransportState to UP;
   *  subclass constructor can rely on this default value.
   */
  Transport();

  virtual
  ~Transport();

public:
  /** \brief set Face and LinkService for Transport
   *  \pre setFaceAndLinkService has not been called
   */
  void
  setFaceAndLinkService(Face& face, LinkService& service);

  /** \return Face to which this Transport is attached
   */
  const Face*
  getFace() const;

  /** \return LinkService to which this Transport is attached
   */
  const LinkService*
  getLinkService() const;

  /** \return LinkService to which this Transport is attached
   */
  LinkService*
  getLinkService();

  virtual const Counters&
  getCounters() const;

public: // upper interface
  /** \brief Request the transport to be closed
   *
   *  This operation is effective only if transport is in UP or DOWN state,
   *  otherwise it has no effect.
   *  The transport changes state to CLOSING, and performs cleanup procedure.
   *  The state will be changed to CLOSED when cleanup is complete, which may
   *  happen synchronously or asynchronously.
   */
  void
  close();

  /** \brief Send a link-layer packet
   *  \param packet the packet to be sent, must be a valid and well-formed TLV block
   *  \note This operation has no effect if getState() is neither UP nor DOWN
   *  \warning Behavior is undefined if packet size exceeds the MTU limit
   */
  void
  send(const Block& packet);

public: // static properties
  /** \return a FaceUri representing local endpoint
   */
  FaceUri
  getLocalUri() const;

  /** \return a FaceUri representing remote endpoint
   */
  FaceUri
  getRemoteUri() const;

  /** \return whether face is local or non-local for scope control purpose
   */
  ndn::nfd::FaceScope
  getScope() const;

  /** \return face persistency setting
   */
  ndn::nfd::FacePersistency
  getPersistency() const;

  /** \brief check whether the face persistency can be changed to \p newPersistency
   *
   *  This function serves as the external API, and invokes the protected function
   *  canChangePersistencyToImpl to perform further checks if \p newPersistency differs
   *  from the current persistency.
   *
   *  \return true if the change can be performed, false otherwise
   */
  bool
  canChangePersistencyTo(ndn::nfd::FacePersistency newPersistency) const;

  /** \brief changes face persistency setting
   */
  void
  setPersistency(ndn::nfd::FacePersistency newPersistency);

  /** \return the link type of the transport
   */
  ndn::nfd::LinkType
  getLinkType() const;

  /** \return maximum payload size
   *  \retval MTU_UNLIMITED transport has no limit on payload size
   *
   *  This size is the maximum packet size that can be sent or received through this transport.
   *
   *  For a datagram-based transport, this is typically the Maximum Transmission Unit (MTU),
   *  after the overhead of headers introduced by the transport has been accounted for.
   *  For a stream-based transport, this is typically unlimited (MTU_UNLIMITED).
   */
  ssize_t
  getMtu() const;

  /** \return capacity of the send queue (in bytes)
   *  \retval QUEUE_UNSUPPORTED transport does not support queue capacity retrieval
   *  \retval QUEUE_ERROR transport was unable to retrieve the queue capacity
   */
  ssize_t
  getSendQueueCapacity() const;

public: // dynamic properties
  /** \return transport state
   */
  TransportState
  getState() const;

  /** \brief signals when transport state changes
   */
  signal::Signal<Transport, TransportState/*old*/, TransportState/*new*/> afterStateChange;

  /** \return expiration time of the transport
   *  \retval time::steady_clock::TimePoint::max() the transport has indefinite lifetime
   */
  time::steady_clock::TimePoint
  getExpirationTime() const;

  /** \return current send queue length of the transport (in octets)
   *  \retval QUEUE_UNSUPPORTED transport does not support queue length retrieval
   *  \retval QUEUE_ERROR transport was unable to retrieve the queue length
   */
  virtual ssize_t
  getSendQueueLength()
  {
    return QUEUE_UNSUPPORTED;
  }

protected: // upper interface to be invoked by subclass
  /**
   * \brief Pass a received link-layer packet to the upper layer for further processing.
   * \param packet The received packet, must be a valid and well-formed TLV block
   * \param endpoint The source endpoint, optional for unicast transports
   * \warning Behavior is undefined if packet size exceeds the MTU limit.
   */
  void
  receive(const Block& packet, const EndpointId& endpoint = {});

protected: // properties to be set by subclass
  void
  setLocalUri(const FaceUri& uri);

  void
  setRemoteUri(const FaceUri& uri);

  void
  setScope(ndn::nfd::FaceScope scope);

  void
  setLinkType(ndn::nfd::LinkType linkType);

  void
  setMtu(ssize_t mtu);

  void
  setSendQueueCapacity(ssize_t sendQueueCapacity);

  /** \brief set transport state
   *
   *  Only the following transitions are valid:
   *  UP->DOWN, DOWN->UP, UP/DOWN->CLOSING/FAILED, CLOSING/FAILED->CLOSED
   *
   *  \throw std::runtime_error transition is invalid.
   */
  void
  setState(TransportState newState);

  void
  setExpirationTime(const time::steady_clock::TimePoint& expirationTime);

protected: // to be overridden by subclass
  /** \brief invoked by canChangePersistencyTo to perform the check
   *
   *  Base class implementation returns false.
   *
   *  \param newPersistency the new persistency, guaranteed to be different from current persistency
   */
  virtual bool
  canChangePersistencyToImpl(ndn::nfd::FacePersistency newPersistency) const;

  /** \brief invoked after the persistency has been changed
   *
   *  The base class implementation does nothing.
   *  When overridden in a subclass, the function should update internal states
   *  after persistency setting has been changed.
   */
  virtual void
  afterChangePersistency(ndn::nfd::FacePersistency oldPersistency);

  /** \brief performs Transport specific operations to close the transport
   *
   *  This is invoked once by \p close() after changing state to CLOSING.
   *  It will not be invoked by Transport class if the transport is already CLOSING or CLOSED.
   *
   *  When the cleanup procedure is complete, this method should change state to CLOSED.
   *  This transition can happen synchronously or asynchronously.
   */
  virtual void
  doClose() = 0;

private: // to be overridden by subclass
  /** \brief performs Transport specific operations to send a packet
   *  \param packet the packet to be sent, can be assumed to be valid and well-formed
   *  \pre transport state is either UP or DOWN
   */
  virtual void
  doSend(const Block& packet) = 0;

private:
  Face* m_face;
  LinkService* m_service;
  FaceUri m_localUri;
  FaceUri m_remoteUri;
  ndn::nfd::FaceScope m_scope;
  ndn::nfd::FacePersistency m_persistency;
  ndn::nfd::LinkType m_linkType;
  ssize_t m_mtu;
  ssize_t m_sendQueueCapacity;
  TransportState m_state;
  time::steady_clock::TimePoint m_expirationTime;
};

inline const Face*
Transport::getFace() const
{
  return m_face;
}

inline const LinkService*
Transport::getLinkService() const
{
  return m_service;
}

inline LinkService*
Transport::getLinkService()
{
  return m_service;
}

inline const Transport::Counters&
Transport::getCounters() const
{
  return *this;
}

inline FaceUri
Transport::getLocalUri() const
{
  return m_localUri;
}

inline void
Transport::setLocalUri(const FaceUri& uri)
{
  m_localUri = uri;
}

inline FaceUri
Transport::getRemoteUri() const
{
  return m_remoteUri;
}

inline void
Transport::setRemoteUri(const FaceUri& uri)
{
  m_remoteUri = uri;
}

inline ndn::nfd::FaceScope
Transport::getScope() const
{
  return m_scope;
}

inline void
Transport::setScope(ndn::nfd::FaceScope scope)
{
  m_scope = scope;
}

inline ndn::nfd::FacePersistency
Transport::getPersistency() const
{
  return m_persistency;
}

inline ndn::nfd::LinkType
Transport::getLinkType() const
{
  return m_linkType;
}

inline void
Transport::setLinkType(ndn::nfd::LinkType linkType)
{
  m_linkType = linkType;
}

inline ssize_t
Transport::getMtu() const
{
  return m_mtu;
}

inline ssize_t
Transport::getSendQueueCapacity() const
{
  return m_sendQueueCapacity;
}

inline void
Transport::setSendQueueCapacity(ssize_t sendQueueCapacity)
{
  m_sendQueueCapacity = sendQueueCapacity;
}

inline TransportState
Transport::getState() const
{
  return m_state;
}

inline time::steady_clock::TimePoint
Transport::getExpirationTime() const
{
  return m_expirationTime;
}

inline void
Transport::setExpirationTime(const time::steady_clock::TimePoint& expirationTime)
{
  m_expirationTime = expirationTime;
}

std::ostream&
operator<<(std::ostream& os, const FaceLogHelper<Transport>& flh);

template<typename T>
std::enable_if_t<std::is_base_of_v<Transport, T> && !std::is_same_v<Transport, T>,
                 std::ostream&>
operator<<(std::ostream& os, const FaceLogHelper<T>& flh)
{
  return os << FaceLogHelper<Transport>(flh.obj);
}

} // namespace nfd::face

#endif // NFD_DAEMON_FACE_TRANSPORT_HPP
