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

#include "unix-stream-channel.hpp"

#include <boost/filesystem.hpp>

namespace nfd {

NFD_LOG_INIT("UnixStreamChannel");

using namespace boost::asio::local;

UnixStreamChannel::UnixStreamChannel(boost::asio::io_service& ioService,
                                     const unix_stream::Endpoint& endpoint)
  : m_ioService(ioService)
  , m_endpoint(endpoint)
{
}

UnixStreamChannel::~UnixStreamChannel()
{
  if (m_acceptor)
    {
      // use the non-throwing variants during destruction
      // and ignore any errors
      boost::system::error_code error;
      m_acceptor->close(error);
      boost::filesystem::remove(m_endpoint.path(), error);
    }
}

void
UnixStreamChannel::listen(const FaceCreatedCallback& onFaceCreated,
                          const ConnectFailedCallback& onAcceptFailed,
                          int backlog/* = acceptor::max_connections*/)
{
  if (m_acceptor) // already listening
    return;

  namespace fs = boost::filesystem;
  fs::path p(m_endpoint.path());
  if (fs::symlink_status(p).type() == fs::socket_file)
    {
      // for safety, remove an already existing file only if it's a socket
      fs::remove(p);
    }

  m_acceptor = make_shared<stream_protocol::acceptor>(boost::ref(m_ioService));
  m_acceptor->open(m_endpoint.protocol());
  m_acceptor->bind(m_endpoint);
  m_acceptor->listen(backlog);

  shared_ptr<stream_protocol::socket> clientSocket =
    make_shared<stream_protocol::socket>(boost::ref(m_ioService));
  m_acceptor->async_accept(*clientSocket,
                           bind(&UnixStreamChannel::handleSuccessfulAccept, this, _1,
                                clientSocket, onFaceCreated, onAcceptFailed));
}

void
UnixStreamChannel::createFace(const shared_ptr<stream_protocol::socket>& socket,
                              const FaceCreatedCallback& onFaceCreated)
{
  shared_ptr<UnixStreamFace> face = make_shared<UnixStreamFace>(boost::cref(socket));
  onFaceCreated(face);
}

void
UnixStreamChannel::handleSuccessfulAccept(const boost::system::error_code& error,
                                          const shared_ptr<stream_protocol::socket>& socket,
                                          const FaceCreatedCallback& onFaceCreated,
                                          const ConnectFailedCallback& onAcceptFailed)
{
  if (error) {
    if (error == boost::system::errc::operation_canceled) // when socket is closed by someone
      return;

    NFD_LOG_DEBUG("Connection failed: "
                  << error.category().message(error.value()));

    onAcceptFailed("Connection failed: " +
                   error.category().message(error.value()));
    return;
  }

  // prepare accepting the next connection
  shared_ptr<stream_protocol::socket> clientSocket =
    make_shared<stream_protocol::socket>(boost::ref(m_ioService));
  m_acceptor->async_accept(*clientSocket,
                           bind(&UnixStreamChannel::handleSuccessfulAccept, this, _1,
                                clientSocket, onFaceCreated, onAcceptFailed));

  NFD_LOG_DEBUG("[" << m_endpoint << "] << Incoming connection");
  createFace(socket, onFaceCreated);
}

} // namespace nfd
