#ifndef __service_position_h__
#define __service_position_h__

#include <string>
#include <list>
#include <boost/asio.hpp>
#include <boost/thread.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/atomic.hpp>
#include <chrono>
#include <boost/serialization/singleton.hpp>

struct info_data{
    boost::shared_ptr<std::string> p_msg;
    std::chrono::system_clock::time_point time_receive;
};

typedef std::shared_ptr<info_data> info_data_ptr;

class info_send{
    public:
        std::string id;
        boost::posix_time::ptime time_last_send;
        std::list<info_data_ptr> data;
        std::shared_ptr<boost::asio::deadline_timer> p_timer;
        double feq;
        std::size_t count_max = 3;
};

typedef std::shared_ptr<info_send> info_send_ptr;
class service_position: public boost::enable_shared_from_this<service_position>{
    public:
        typedef boost::shared_ptr<boost::asio::io_service> service_ptr;
        typedef boost::shared_ptr<boost::asio::ip::tcp::socket> socket_ptr;
        typedef boost::shared_ptr<boost::asio::ip::tcp::acceptor> acceptor_ptr;
        typedef boost::shared_ptr<std::string> buffer_ptr;
    public:
        virtual void notify(const std::string& msg, const std::string& id, const double& feq);
        virtual void set_port(const int port);
        virtual bool start();
        virtual void stop();
    protected:
        int m_port;
        service_ptr m_service;
        std::list<socket_ptr> m_sockets;
        acceptor_ptr m_acceptor;
        boost::thread m_thread;
        boost::atomic_bool m_stop;

        std::map<std::string, info_send_ptr> m_deques;
        std::mutex m_mutex;
        std::shared_ptr<boost::asio::deadline_timer> mp_timer;
    protected:
        virtual void handle_thread(service_ptr p_service);
        virtual void handle_acceptor(const boost::system::error_code& ec, socket_ptr p_socket);
        virtual void handle_stop();
        virtual void handle_notify(buffer_ptr pBuffer);
        virtual void handle_write(const boost::system::error_code& ec, unsigned int bytes_transferred, socket_ptr p_socket, buffer_ptr p_buffer);
        virtual void handle_buffer(buffer_ptr p_buffer, std::string id, double feq, service_ptr p_service);
        virtual void handle_timer(const boost::system::error_code& ec, std::weak_ptr<info_send> p_info);
        virtual std::string to_str(const std::chrono::system_clock::time_point& time);
        virtual void init_cache(info_send_ptr& p_info);
};

typedef boost::shared_ptr<service_position> service_position_ptr;

#endif