/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2014-2015,  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 "core/counter.hpp"
#include "face-log.hpp"
#include <ndn-cxx/encoding/nfd-constants.hpp>

namespace nfd {
namespace face {

class LpFace;
class LinkService;

/** \brief indicates the state of a transport
 */
enum class TransportState {
  NONE,
  UP, ///< the transport is up
  DOWN, ///< the transport is down temporarily, and is being recovered
  CLOSING, ///< the transport is requested to be closed
  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 Transport
 *  \note The type name 'TransportCounters' is 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 the transport has no limit on payload size
 */
const ssize_t MTU_UNLIMITED = -1;

/** \brief (for internal use) indicates MTU field is unset
 */
const ssize_t MTU_INVALID = -2;

/** \brief the lower part of an LpFace
 *  \sa LpFace
 */
class Transport : protected virtual TransportCounters, noncopyable
{
public:
  /** \brief identifies an endpoint on the link
   */
  typedef uint64_t EndpointId;

  /** \brief stores a packet along with the remote endpoint
   */
  class Packet
  {
  public:
    Packet() = default;

    explicit
    Packet(Block&& packet);

  public:
    /** \brief the packet as a TLV block
     */
    Block packet;

    /** \brief identifies the remote endpoint
     *
     *  This ID is only meaningful in the context of the same Transport.
     *  Incoming packets from the same remote endpoint have the same EndpointId,
     *  and incoming packets from different remote endpoints have different EndpointIds.
     */
    EndpointId remoteEndpoint;
  };

  /** \brief counters provided by Transport
   */
  typedef TransportCounters Counters;

  /** \brief constructor
   *
   *  Transport 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(LpFace& face, LinkService& service);

  /** \return Face to which this Transport is attached
   */
  const LpFace*
  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
   *  \note This operation has no effect if \p getState() is neither UP nor DOWN
   *  \warning undefined behavior if packet size exceeds MTU limit
   */
  void
  send(Packet&& packet);

protected: // upper interface to be invoked by subclass
  /** \brief receive a link-layer packet
   *  \warning undefined behavior if packet size exceeds MTU limit
   */
  void
  receive(Packet&& 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 changes face persistency setting
   */
  void
  setPersistency(ndn::nfd::FacePersistency persistency);

  /** \return whether face is point-to-point or multi-access
   */
  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;

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

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

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);

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

protected: // to be overridden by subclass
  /** \brief invoked before persistency is changed
   *  \throw std::invalid_argument new persistency is not supported
   *  \throw std::runtime_error transition is disallowed
   */
  virtual void
  beforeChangePersistency(ndn::nfd::FacePersistency newPersistency) = 0;

  /** \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, which must be a well-formed TLV block
   *  \pre state is either UP or DOWN
   */
  virtual void
  doSend(Packet&& packet) = 0;

private:
  LpFace* 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;
  TransportState m_state;
};

inline const LpFace*
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 void
Transport::setMtu(ssize_t mtu)
{
  BOOST_ASSERT(mtu == MTU_UNLIMITED || mtu > 0);
  m_mtu = mtu;
}

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

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

template<typename T>
typename std::enable_if<std::is_base_of<Transport, T>::value &&
                        !std::is_same<Transport, T>::value, std::ostream&>::type
operator<<(std::ostream& os, const FaceLogHelper<T>& flh)
{
  return os << FaceLogHelper<Transport>(flh.obj);
}

} // namespace face
} // namespace nfd

#endif // NFD_DAEMON_FACE_TRANSPORT_HPP
