/* -*- 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/>.
 */

#include "face/unix-stream-channel.hpp"

#include "channel-fixture.hpp"

#include <boost/filesystem.hpp>
#include <fstream>

namespace nfd::tests {

namespace fs = boost::filesystem;
namespace local = boost::asio::local;
using face::UnixStreamChannel;

class UnixStreamChannelFixture : public ChannelFixture<UnixStreamChannel, unix_stream::Endpoint>
{
protected:
  UnixStreamChannelFixture()
  {
    listenerEp = unix_stream::Endpoint("nfd-test-unix-stream-channel.sock");
  }

  shared_ptr<UnixStreamChannel>
  makeChannel() final
  {
    return std::make_shared<UnixStreamChannel>(listenerEp, false);
  }

  void
  listen()
  {
    listenerChannel = makeChannel();
    listenerChannel->listen(
      [this] (const shared_ptr<Face>& newFace) {
        BOOST_REQUIRE(newFace != nullptr);
        connectFaceClosedSignal(*newFace, [this] { limitedIo.afterOp(); });
        listenerFaces.push_back(newFace);
        limitedIo.afterOp();
      },
      ChannelFixture::unexpectedFailure);
  }

  void
  clientConnect(local::stream_protocol::socket& client)
  {
    client.async_connect(listenerEp,
      [this] (const boost::system::error_code& error) {
        BOOST_REQUIRE_EQUAL(error, boost::system::errc::success);
        limitedIo.afterOp();
      });
  }
};

BOOST_AUTO_TEST_SUITE(Face)
BOOST_FIXTURE_TEST_SUITE(TestUnixStreamChannel, UnixStreamChannelFixture)

BOOST_AUTO_TEST_CASE(Uri)
{
  auto channel = makeChannel();
  BOOST_CHECK_EQUAL(channel->getUri(), FaceUri(listenerEp));
}

BOOST_AUTO_TEST_CASE(Listen)
{
  auto channel = makeChannel();
  BOOST_CHECK_EQUAL(channel->isListening(), false);

  channel->listen(nullptr, nullptr);
  BOOST_CHECK_EQUAL(channel->isListening(), true);

  // listen() is idempotent
  BOOST_CHECK_NO_THROW(channel->listen(nullptr, nullptr));
  BOOST_CHECK_EQUAL(channel->isListening(), true);
}

BOOST_AUTO_TEST_CASE(MultipleAccepts)
{
  this->listen();

  BOOST_CHECK_EQUAL(listenerChannel->isListening(), true);
  BOOST_CHECK_EQUAL(listenerChannel->size(), 0);

  local::stream_protocol::socket client1(g_io);
  this->clientConnect(client1);

  BOOST_CHECK_EQUAL(limitedIo.run(2, 1_s), LimitedIo::EXCEED_OPS);
  BOOST_CHECK_EQUAL(listenerChannel->size(), 1);

  local::stream_protocol::socket client2(g_io);
  local::stream_protocol::socket client3(g_io);
  this->clientConnect(client2);
  this->clientConnect(client3);

  BOOST_CHECK_EQUAL(limitedIo.run(4, 1_s), LimitedIo::EXCEED_OPS);
  BOOST_CHECK_EQUAL(listenerChannel->size(), 3);
  BOOST_CHECK_EQUAL(listenerFaces.size(), 3);

  // check face persistency and channel association
  for (const auto& face : listenerFaces) {
    BOOST_CHECK_EQUAL(face->getPersistency(), ndn::nfd::FACE_PERSISTENCY_ON_DEMAND);
    BOOST_CHECK_EQUAL(face->getChannel().lock(), listenerChannel);
  }
}

BOOST_AUTO_TEST_CASE(SocketFile)
{
  fs::path socketPath(listenerEp.path());
  fs::remove(socketPath);

  auto channel = makeChannel();
  BOOST_CHECK_EQUAL(fs::symlink_status(socketPath).type(), fs::file_not_found);

  channel->listen(nullptr, nullptr);
  auto status = fs::symlink_status(socketPath);
  BOOST_CHECK_EQUAL(status.type(), fs::socket_file);
  BOOST_CHECK_EQUAL(status.permissions(), fs::owner_read | fs::group_read | fs::others_read |
                                          fs::owner_write | fs::group_write | fs::others_write);

  channel.reset();
  BOOST_CHECK_EQUAL(fs::symlink_status(socketPath).type(), fs::file_not_found);
}

BOOST_AUTO_TEST_CASE(ExistingStaleSocketFile)
{
  fs::path socketPath(listenerEp.path());
  fs::remove(socketPath);

  local::stream_protocol::acceptor acceptor(g_io, listenerEp);
  acceptor.close();
  BOOST_CHECK_EQUAL(fs::symlink_status(socketPath).type(), fs::socket_file);

  auto channel = makeChannel();
  BOOST_CHECK_NO_THROW(channel->listen(nullptr, nullptr));
  BOOST_CHECK_EQUAL(fs::symlink_status(socketPath).type(), fs::socket_file);
}

BOOST_AUTO_TEST_CASE(ExistingRegularFile)
{
  fs::path socketPath(listenerEp.path());
  fs::remove(socketPath);

  std::ofstream f(listenerEp.path());
  f.close();

  auto channel = makeChannel();
  BOOST_CHECK_THROW(channel->listen(nullptr, nullptr), UnixStreamChannel::Error);

  fs::remove(socketPath);
}

BOOST_AUTO_TEST_SUITE_END() // TestUnixStreamChannel
BOOST_AUTO_TEST_SUITE_END() // Face

} // namespace nfd::tests
