#pragma once

#include "ITaskListener.h"
#include <set>
#include <boost/asio.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/thread.hpp>
#include <vector>
#include "ConcurrentQueue.h"
#include "../../Utils/CriticalSection.h"
#include "BackgroundWorker.h"

namespace MP
{
  class LogServer : public ITaskListener, public BackgroundWorker<std::vector<unsigned char> >
  { 
  public:
    typedef task_type RawData;
  private:
    boost::asio::io_service m_service;

    const unsigned short m_port;
    boost::asio::ip::tcp::acceptor * m_acceptor;
    boost::thread m_acceptorThread;
    RawData m_threadInfoMsg;
    volatile bool m_running;

    class Connection : boost::noncopyable
    {
      boost::asio::ip::tcp::socket m_sck;
    public:
      Connection(boost::asio::io_service &service) : m_sck(service) {}

      ~Connection();

      bool accept(boost::asio::ip::tcp::acceptor & acc);
      
      bool send(const RawData & data);
    };
    mutable CriticalSection m_connLock;
    typedef Connection * ConnectionPtr;
    typedef std::set<ConnectionPtr> ConnectionSet;

    mutable ConnectionSet m_clients;

    void accept();
  protected:
    virtual void handle(const RawData &data) const;
  public:
    virtual void onTaskStarted(const TaskEvent &ev);
    virtual void onTaskEnded(const TaskEvent &ev);

    explicit LogServer(unsigned short port);
    ~LogServer();

    void open(DWORD mainThread, const std::vector<DWORD> &workerThreads);
  };
}