#ifndef TCP_SERVER_H
#define TCP_SERVER_H

#include "boost_comm.h"

#include "tcp_client.h"
#include "session_manager.h"
#include "command_machine.h"
#include "task_engine.h"
#include "search_engine.h"

using namespace boost::asio;

namespace seemmo
{
class tcp_server
{
public:
tcp_server(const char *ip, int port, bool enprint = true);
~tcp_server();
public:
typedef ip::tcp::socket socket_type;
typedef std::shared_ptr<socket_type> sock_ptr;
protected:
void run()
{
m_io.run();
}

void func_run()
{
func_io.run();
}
boost::asio::deadline_timer *m_timer;
bool enable_print;
/* boost::asio::placeholders::error*/
public:
void print()
{
using namespace boost::posix_time;
ptime now = second_clock::local_time();
string now_str = to_iso_extended_string(now.date()) + " " + to_simple_string(now.time_of_day());
cout << now_str << " ";

/*std::string strTime = boost::posix_time::to_iso_string(boost::posix_time::second_clock::local_time());
// 这时候strTime里存放时间的格式是YYYYMMDDTHHMMSS,日期和时间用大写字母T隔开了
int pos = strTime.find('T');
strTime.replace(pos, 1, std::string("-"));
strTime.replace(pos + 3, 0, std::string(":"));
strTime.replace(pos + 6, 0, std::string(":"));
std::cout << strTime.c_str() <<" ";*/
session_manager::print();
command_machine::print();
task_engine::print();
search_engine::print();
cout << endl;

m_timer->expires_at(m_timer->expires_at() + boost::posix_time::seconds(3));
m_timer->async_wait(boost::bind(&tcp_server::print, this));
}
#ifdef ENABLE_BOOST_THREAD
void start()
{
for (int num = 0; num < 4; num++)
group_.create_thread(bind(&tcp_server::run, this));
group_.create_thread(bind(&tcp_server::func_run, this));
}
void stop()
{
group_.join_all();
}
thread_group group_;
#endif
protected:
socket_type *m_sock;
private:
void post_accept();
void accept_handler(const boost::system::error_code& ec, sock_ptr sock);
private:
io_service m_io;
io_service func_io;
ip::tcp::acceptor m_acceptor;
};
}

#endif // TCP_SERVER_H


#include "tcp_server.h"

namespace seemmo
{
tcp_server::tcp_server(const char *ip, int port, bool enprint)
:m_acceptor(m_io, ip::tcp::endpoint(ip::tcp::v4(), port)),
enable_print(enprint)
{
if (enable_print)
{
m_timer = new boost::asio::deadline_timer(m_io, boost::posix_time::seconds(3));
m_timer->async_wait(boost::bind(&tcp_server::print, this));
}

session_manager::start_construct();
m_acceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
post_accept();//multi cast post accepter
}
tcp_server::~tcp_server()
{
if (enable_print)
{
delete m_timer;
}
}
void tcp_server::post_accept()
{
sock_ptr sock(new socket_type(m_io));

m_acceptor.async_accept(*sock,
std::bind(&tcp_server::accept_handler, this, std::placeholders::_1, sock));
}
void tcp_server::accept_handler(const boost::system::error_code& ec, sock_ptr sock)
{
if (ec)
{
return;
}

boost::format fmt("client:%1%:%2%");
fmt % sock->remote_endpoint().address().to_string();
fmt % sock->remote_endpoint().port();
//LOG(INFO)<<fmt.str()<<LOG_END;

session_manager::new_session(sock);

post_accept();
}
}