//
// third_party_lib.cpp
// ~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

#include <asio.hpp>
#include <array>
#include <iostream>
#include <memory>

using asio::ip::tcp;

namespace third_party_lib {

// Simulation of a third party library that wants to perform read and write
// operations directly on a socket. It needs to be polled to determine whether
// it requires a read or write operation, and notified when the socket is ready
// for reading or writing.
class session
{
public:
  session(tcp::socket& socket)
    : socket_(socket)
  {
  }

  // Returns true if the third party library wants to be notified when the
  // socket is ready for reading.
  bool want_read() const
  {
    return state_ == reading;
  }

  // Notify that third party library that it should perform its read operation.
  void do_read(std::error_code& ec)
  {
    if (std::size_t len = socket_.read_some(asio::buffer(data_), ec))
    {
      write_buffer_ = asio::buffer(data_, len);
      state_ = writing;
    }
  }

  // Returns true if the third party library wants to be notified when the
  // socket is ready for writing.
  bool want_write() const
  {
    return state_ == writing;
  }

  // Notify that third party library that it should perform its write operation.
  void do_write(std::error_code& ec)
  {
    if (std::size_t len = socket_.write_some(
          asio::buffer(write_buffer_), ec))
    {
      write_buffer_ = write_buffer_ + len;
      state_ = asio::buffer_size(write_buffer_) > 0 ? writing : reading;
    }
  }

private:
  tcp::socket& socket_;
  enum { reading, writing } state_ = reading;
  std::array<char, 128> data_;
  asio::const_buffer write_buffer_;
};

} // namespace third_party_lib

// The glue between asio's sockets and the third party library.
class connection
  : public std::enable_shared_from_this<connection>
{
public:
  connection(tcp::socket socket)
    : socket_(std::move(socket))
  {
  }

  void start()
  {
    // Put the socket into non-blocking mode.
    socket_.non_blocking(true);

    do_operations();
  }

private:
  void do_operations()
  {
    auto self(shared_from_this());

    // Start a read operation if the third party library wants one.
    if (session_impl_.want_read() && !read_in_progress_)
    {
      read_in_progress_ = true;
      socket_.async_wait(tcp::socket::wait_read,
          [this, self](std::error_code ec)
          {
            read_in_progress_ = false;

            // Notify third party library that it can perform a read.
            if (!ec)
              session_impl_.do_read(ec);

            // The third party library successfully performed a read on the
            // socket. Start new read or write operations based on what it now
            // wants.
            if (!ec || ec == asio::error::would_block)
              do_operations();

            // Otherwise, an error occurred. Closing the socket cancels any
            // outstanding asynchronous read or write operations. The
            // connection object will be destroyed automatically once those
            // outstanding operations complete.
            else
              socket_.close();
          });
    }

    // Start a write operation if the third party library wants one.
    if (session_impl_.want_write() && !write_in_progress_)
    {
      write_in_progress_ = true;
      socket_.async_wait(tcp::socket::wait_write,
          [this, self](std::error_code ec)
          {
            write_in_progress_ = false;

            // Notify third party library that it can perform a write.
            if (!ec)
              session_impl_.do_write(ec);

            // The third party library successfully performed a write on the
            // socket. Start new read or write operations based on what it now
            // wants.
            if (!ec || ec == asio::error::would_block)
              do_operations();

            // Otherwise, an error occurred. Closing the socket cancels any
            // outstanding asynchronous read or write operations. The
            // connection object will be destroyed automatically once those
            // outstanding operations complete.
            else
              socket_.close();
          });
    }
  }

private:
  tcp::socket socket_;
  third_party_lib::session session_impl_{socket_};
  bool read_in_progress_ = false;
  bool write_in_progress_ = false;
};

class server
{
public:
  server(asio::io_context& io_context, unsigned short port)
    : acceptor_(io_context, {tcp::v4(), port})
  {
    do_accept();
  }

private:
  void do_accept()
  {
    acceptor_.async_accept(
        [this](std::error_code ec, tcp::socket socket)
        {
          if (!ec)
          {
            std::make_shared<connection>(std::move(socket))->start();
          }

          do_accept();
        });
  }

  tcp::acceptor acceptor_;
};

int main(int argc, char* argv[])
{
  try
  {
    if (argc != 2)
    {
      std::cerr << "Usage: third_party_lib <port>\n";
      return 1;
    }

    asio::io_context io_context;

    server s(io_context, std::atoi(argv[1]));

    io_context.run();
  }
  catch (std::exception& e)
  {
    std::cerr << "Exception: " << e.what() << "\n";
  }

  return 0;
}
