/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (C) 2014 Named Data Networking Project
 * See COPYING for copyright and distribution information.
 */

#ifndef NFD_FACE_STREAM_FACE_HPP
#define NFD_FACE_STREAM_FACE_HPP

#include "face.hpp"
#include "local-face.hpp"

namespace nfd {

// forward declaration
template<class T, class U, class V> struct StreamFaceSenderImpl;

template<class Protocol, class FaceBase = Face>
class StreamFace : public FaceBase
{
public:
  typedef Protocol protocol;

  /**
   * \brief Create instance of StreamFace
   */
  explicit
  StreamFace(const FaceUri& uri,
             const shared_ptr<typename protocol::socket>& socket);

  virtual
  ~StreamFace();

  // from Face
  virtual void
  sendInterest(const Interest& interest);

  virtual void
  sendData(const Data& data);

  virtual void
  close();

protected:
  void
  processErrorCode(const boost::system::error_code& error);

  void
  handleSend(const boost::system::error_code& error,
             const Block& header, const Block& payload);
  void
  handleSend(const boost::system::error_code& error,
             const Block& wire);

  void
  handleReceive(const boost::system::error_code& error,
                std::size_t bytes_recvd);

  void
  keepFaceAliveUntilAllHandlersExecuted(const shared_ptr<Face>& face);

  void
  closeSocket();

protected:
  shared_ptr<typename protocol::socket> m_socket;

private:
  uint8_t m_inputBuffer[MAX_NDN_PACKET_SIZE];
  std::size_t m_inputBufferSize;

  friend struct StreamFaceSenderImpl<Protocol, FaceBase, Interest>;
  friend struct StreamFaceSenderImpl<Protocol, FaceBase, Data>;

  NFD_LOG_INCLASS_DECLARE();
};

// All inherited classes must use
// NFD_LOG_INCLASS_TEMPLATE_SPECIALIZATION_DEFINE(StreamFace, <specialization-parameter>, "Name");


/** \brief Class allowing validation of the StreamFace use
 *
 *  For example, partial specialization based on boost::asio::ip::tcp should check
 *  that local endpoint is loopback
 *
 *  @throws Face::Error if validation failed
 */
template<class Protocol, class U>
struct StreamFaceValidator
{
  static void
  validateSocket(typename Protocol::socket& socket)
  {
  }
};


template<class T, class FaceBase>
inline
StreamFace<T, FaceBase>::StreamFace(const FaceUri& uri,
                                    const shared_ptr<typename StreamFace::protocol::socket>& socket)
  : FaceBase(uri)
  , m_socket(socket)
  , m_inputBufferSize(0)
{
  StreamFaceValidator<T, FaceBase>::validateSocket(*socket);
  m_socket->async_receive(boost::asio::buffer(m_inputBuffer, MAX_NDN_PACKET_SIZE), 0,
                          bind(&StreamFace<T, FaceBase>::handleReceive, this, _1, _2));
}

template<class T, class U>
inline
StreamFace<T, U>::~StreamFace()
{
}

template<class Protocol, class FaceBase, class Packet>
struct StreamFaceSenderImpl
{
  static void
  send(StreamFace<Protocol, FaceBase>& face, const Packet& packet)
  {
    face.m_socket->async_send(boost::asio::buffer(packet.wireEncode().wire(),
                                                  packet.wireEncode().size()),
                              bind(&StreamFace<Protocol, FaceBase>::handleSend,
                                   &face, _1, packet.wireEncode()));
  }
};

// partial specialization (only classes can be partially specialized)
template<class Protocol, class Packet>
struct StreamFaceSenderImpl<Protocol, LocalFace, Packet>
{
  static void
  send(StreamFace<Protocol, LocalFace>& face, const Packet& packet)
  {
    using namespace boost::asio;

    if (face.isEmptyFilteredLocalControlHeader(packet.getLocalControlHeader()))
      {
        const Block& payload = packet.wireEncode();
        face.m_socket->async_send(buffer(payload.wire(), payload.size()),
                                  bind(&StreamFace<Protocol, LocalFace>::handleSend,
                                       &face, _1, packet.wireEncode()));
      }
    else
      {
        Block header = face.filterAndEncodeLocalControlHeader(packet);
        const Block& payload = packet.wireEncode();

        std::vector<const_buffer> buffers;
        buffers.reserve(2);
        buffers.push_back(buffer(header.wire(),  header.size()));
        buffers.push_back(buffer(payload.wire(), payload.size()));

        face.m_socket->async_send(buffers,
                                  bind(&StreamFace<Protocol, LocalFace>::handleSend,
                                       &face, _1, header, payload));
      }
  }
};


template<class T, class U>
inline void
StreamFace<T, U>::sendInterest(const Interest& interest)
{
  StreamFaceSenderImpl<T, U, Interest>::send(*this, interest);
}

template<class T, class U>
inline void
StreamFace<T, U>::sendData(const Data& data)
{
  StreamFaceSenderImpl<T, U, Data>::send(*this, data);
}

template<class T, class U>
inline void
StreamFace<T, U>::close()
{
  if (!m_socket->is_open())
    return;

  NFD_LOG_INFO("[id:" << this->getId()
               << ",endpoint:" << m_socket->local_endpoint()
               << "] Close connection");

  closeSocket();
  this->onFail("Close connection");
}

template<class T, class U>
inline void
StreamFace<T, U>::processErrorCode(const boost::system::error_code& error)
{
  if (error == boost::system::errc::operation_canceled) // when socket is closed by someone
    return;

  if (!m_socket->is_open())
    {
      this->onFail("Connection closed");
      return;
    }

  if (error == boost::asio::error::eof)
    {
      NFD_LOG_INFO("[id:" << this->getId()
                   << ",endpoint:" << m_socket->local_endpoint()
                   << "] Connection closed");
    }
  else
    {
      NFD_LOG_WARN("[id:" << this->getId()
                   << ",endpoint:" << m_socket->local_endpoint()
                   << "] Send or receive operation failed, closing socket: "
                   << error.category().message(error.value()));
    }

  closeSocket();

  if (error == boost::asio::error::eof)
    {
      this->onFail("Connection closed");
    }
  else
    {
      this->onFail("Send or receive operation failed, closing socket: " +
                   error.category().message(error.value()));
    }
}


template<class T, class U>
inline void
StreamFace<T, U>::handleSend(const boost::system::error_code& error,
                             const Block& wire)
{
  if (error)
    return processErrorCode(error);

  NFD_LOG_TRACE("[id:" << this->getId()
                << ",endpoint:" << m_socket->local_endpoint()
                << "] Successfully sent: " << wire.size() << " bytes");
}

template<class T, class U>
inline void
StreamFace<T, U>::handleSend(const boost::system::error_code& error,
                             const Block& header, const Block& payload)
{
  if (error)
    return processErrorCode(error);

  NFD_LOG_TRACE("[id:" << this->getId()
                << ",endpoint:" << m_socket->local_endpoint()
                << "] Successfully sent: " << (header.size()+payload.size()) << " bytes");
}

template<class T, class U>
inline void
StreamFace<T, U>::handleReceive(const boost::system::error_code& error,
                             std::size_t bytes_recvd)
{
  if (error)
    return processErrorCode(error);

  NFD_LOG_TRACE("[id:" << this->getId()
                << ",endpoint:" << m_socket->local_endpoint()
                << "] Received: " << bytes_recvd << " bytes");

  m_inputBufferSize += bytes_recvd;
  // do magic

  std::size_t offset = 0;
  /// @todo Eliminate reliance on exceptions in this path
  try {
    while(m_inputBufferSize - offset > 0)
      {
        Block element(m_inputBuffer + offset, m_inputBufferSize - offset);
        offset += element.size();

        BOOST_ASSERT(offset <= m_inputBufferSize);

        if (!this->decodeAndDispatchInput(element))
          {
            NFD_LOG_WARN("[id:" << this->getId()
                         << ",endpoint:" << m_socket->local_endpoint()
                         << "] Received unrecognized block of type ["
                         << element.type() << "]");
            // ignore unknown packet and proceed
          }
      }
  }
  catch(const tlv::Error& e) {
    if (m_inputBufferSize == MAX_NDN_PACKET_SIZE && offset == 0)
      {
        NFD_LOG_WARN("[id:" << this->getId()
                     << ",endpoint:" << m_socket->local_endpoint()
                     << "] Received input is invalid or too large to process, "
                     << "closing down the face");

        closeSocket();
        this->onFail("Received input is invalid or too large to process, closing down the face");
        return;
      }
  }

  if (offset > 0)
    {
      if (offset != m_inputBufferSize)
        {
          std::copy(m_inputBuffer + offset, m_inputBuffer + m_inputBufferSize,
                    m_inputBuffer);
          m_inputBufferSize -= offset;
        }
      else
        {
          m_inputBufferSize = 0;
        }
    }

  m_socket->async_receive(boost::asio::buffer(m_inputBuffer + m_inputBufferSize,
                                              MAX_NDN_PACKET_SIZE - m_inputBufferSize), 0,
                          bind(&StreamFace<T, U>::handleReceive, this, _1, _2));
}

template<class T, class U>
inline void
StreamFace<T, U>::keepFaceAliveUntilAllHandlersExecuted(const shared_ptr<Face>& face)
{
}

template<class T, class U>
inline void
StreamFace<T, U>::closeSocket()
{
  boost::asio::io_service& io = m_socket->get_io_service();

  // use the non-throwing variants and ignore errors, if any
  boost::system::error_code error;
  m_socket->shutdown(protocol::socket::shutdown_both, error);
  m_socket->close(error);
  // after this, handlers will be called with an error code

  // ensure that the Face object is alive at least until all pending
  // handlers are dispatched
  io.post(bind(&StreamFace<T, U>::keepFaceAliveUntilAllHandlersExecuted,
               this, this->shared_from_this()));
}

} // namespace nfd

#endif // NFD_FACE_STREAM_FACE_HPP
