#ifndef THREADPOOL_H
#define THREADPOOL_H
#include <thread>
#include <mutex>
#include <functional>
#include <list>
#include <atomic>
#include <vector>
#include <memory>
#include <condition_variable>

namespace my_threadpool{
    //the thread pool class
    class thread_pool
    {
        class worker;
    public:
        thread_pool(int nThreads = 2);
        ~thread_pool();
    public:

        size_t  total_threads();        //total threads;
        void    join();                 //wait until all threads is terminated;
        void    wait_for_idle();        //wait until this thread has no tasks pending.
        void    terminate();            //set the mask to termminiate
        size_t  current_load(size_t n); //return the current load of this thread
        //Append a task to do
        void append(std::function< bool (void) > func);
    protected:
        //NO. threads
        size_t m_n_threads = 0;
        //vector contains all the threads
        std::vector< std::shared_ptr<thread_pool::worker> > m_vec_threads;
    };

    //This class defines a class contains a thread, a task queue
    class thread_pool::worker
    {
    public:
        worker();
        ~worker();
    public:

        void    join();         //wait until this thread is terminated;
        void    wait_for_idle();//wait until this thread has no tasks pending.
        void    terminate();    //set the mask to termminiate
        size_t  current_load(); //return the current load of this thread
        //Append a task to do
        size_t append(std::function< bool (void) > func);
    protected:
        std::atomic< bool>                      m_b_is_finish;          //the thread the next loop will be terminated if this para is true..
        std::list<std::function< bool (void)> > m_list_tasks;           //The Task List contains function objects
        std::mutex                              m_list_tasks_mutex;     //The mutex for task list
        std::shared_ptr<std::thread>            m_pthread;              //thread.
        std::mutex                              m_cond_mutex;           //condition mutex used by m_cond_locker
        std::condition_variable                 m_cond_incoming_task;   //condition to notify the thread for incoming tasks
        std::unique_lock< std::mutex>           m_cond_locker ;
    protected:
        void run();
    };


}
#endif // THREADPOOL_H
