/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2013-2016, Regents of the University of California.
 *
 * This file is part of ChronoShare, a decentralized file sharing application over NDN.
 *
 * ChronoShare 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.
 *
 * ChronoShare 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 copies of the GNU General Public License along with
 * ChronoShare, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
 *
 * See AUTHORS.md for complete list of ChronoShare authors and contributors.
 */
//
// server.cpp
// ~~~~~~~~~~
//
// Copyright (c) 2003-2012 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 "server.hpp"
#include "logging.h"
#include <boost/bind.hpp>
#include <signal.h>

INIT_LOGGER("HttpServer");
namespace http {
namespace server {

server::server(const std::string& address, const std::string& port, const std::string& doc_root)
  : io_service_()
  ,
  // signals_(io_service_),
  acceptor_(io_service_)
  , connection_manager_()
  , new_connection_()
  , request_handler_(doc_root)
{
  // Register to handle the signals that indicate when the server should exit.
  // It is safe to register for the same signal multiple times in a program,
  // provided all registration for the specified signal is made through Asio.
  //  signals_.add(SIGINT);
  //  signals_.add(SIGTERM);
  //#if defined(SIGQUIT)
  //  signals_.add(SIGQUIT);
  //#endif // defined(SIGQUIT)
  //  signals_.async_wait(boost::bind(&server::handle_stop, this));

  // Open the acceptor with the option to reuse the address (i.e. SO_REUSEADDR).
  boost::asio::ip::tcp::resolver resolver(io_service_);
  boost::asio::ip::tcp::resolver::query query(address, port);
  boost::asio::ip::tcp::endpoint endpoint = *resolver.resolve(query);
  acceptor_.open(endpoint.protocol());
  acceptor_.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
  acceptor_.bind(endpoint);
  acceptor_.listen();

  start_accept();

  _LOG_DEBUG("Listen on [" << address << ": " << port << "] with doc_root = " << doc_root);
}

server::~server()
{
  // handle_stop();
}

void
server::run()
{
  // The io_service::run() call will block until all asynchronous operations
  // have finished. While the server is running, there is always at least one
  // asynchronous operation outstanding: the asynchronous accept call waiting
  // for new incoming connections.
  io_service_.run();
}

void
server::start_accept()
{
  new_connection_.reset(new connection(io_service_, connection_manager_, request_handler_));
  acceptor_.async_accept(new_connection_->socket(),
                         boost::bind(&server::handle_accept, this, boost::asio::placeholders::error));
}

void
server::handle_accept(const boost::system::error_code& e)
{
  // Check whether the server was stopped by a signal before this completion
  // handler had a chance to run.
  if (!acceptor_.is_open()) {
    return;
  }

  if (!e) {
    connection_manager_.start(new_connection_);
  }

  start_accept();
}

void
server::handle_stop()
{
  // The server is stopped by cancelling all outstanding asynchronous
  // operations. Once all operations have finished the io_service::run() call
  // will exit.
  acceptor_.close();
  connection_manager_.stop_all();
  // although they say io_service::run() would stop, but it didn't happen..
  // the thread join was blocking, waiting for io_service::run() to finish
  // even after handle_stop() call..
  // so just force it quit, no harm here.
  io_service_.stop();
}

} // namespace server
} // namespace http
